From 7ea084ae895e485c954bea42932a259d451a3976 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 13 Feb 2024 23:45:27 +0100 Subject: [PATCH 01/54] eof --- crates/primitives/src/eof.rs | 3 +++ crates/primitives/src/eof/body.rs | 0 crates/primitives/src/eof/container.rs | 0 crates/primitives/src/eof/header.rs | 31 ++++++++++++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 crates/primitives/src/eof.rs create mode 100644 crates/primitives/src/eof/body.rs create mode 100644 crates/primitives/src/eof/container.rs create mode 100644 crates/primitives/src/eof/header.rs diff --git a/crates/primitives/src/eof.rs b/crates/primitives/src/eof.rs new file mode 100644 index 0000000000..5321b9b25e --- /dev/null +++ b/crates/primitives/src/eof.rs @@ -0,0 +1,3 @@ +pub mod header; +pub mod body; +pub mod container; \ No newline at end of file diff --git a/crates/primitives/src/eof/body.rs b/crates/primitives/src/eof/body.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/crates/primitives/src/eof/container.rs b/crates/primitives/src/eof/container.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/crates/primitives/src/eof/header.rs b/crates/primitives/src/eof/header.rs new file mode 100644 index 0000000000..39910e442b --- /dev/null +++ b/crates/primitives/src/eof/header.rs @@ -0,0 +1,31 @@ +/// EOF Header containing +pub struct Header { + /// 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, +} + +impl Header { + /// Create new EOF Header. + pub fn new( + types_size: u16, + code_sizes: Vec, + container_sizes: Vec, + data_size: u16, + ) -> Self { + Self { + types_size, + code_sizes, + container_sizes, + data_size, + } + } +} From 237068f0a551554891d132e5f285fd9ac898e371 Mon Sep 17 00:00:00 2001 From: rakita Date: Wed, 14 Feb 2024 18:52:23 +0100 Subject: [PATCH 02/54] feat(EOF): Header decoder --- crates/primitives/src/eof/header.rs | 137 ++++++++++++++++++++++++++++ crates/primitives/src/lib.rs | 2 + 2 files changed, 139 insertions(+) diff --git a/crates/primitives/src/eof/header.rs b/crates/primitives/src/eof/header.rs index 39910e442b..737dc37f0b 100644 --- a/crates/primitives/src/eof/header.rs +++ b/crates/primitives/src/eof/header.rs @@ -1,4 +1,5 @@ /// EOF Header containing +#[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct Header { /// Size of EOF types section. /// types section includes num of input and outputs and max stack size. @@ -13,6 +14,55 @@ pub struct Header { pub data_size: u16, } +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_u8(input: &[u8]) -> Result<(&[u8], u8), ()> { + if input.is_empty() { + return Err(()); + } + Ok((&input[1..], input[0])) +} + +#[inline] +fn consume_u16(input: &[u8]) -> Result<(&[u8], u16), ()> { + if input.len() < 2 { + return Err(()); + } + let (int_bytes, rest) = input.split_at(2); + Ok((rest, u16::from_be_bytes([int_bytes[0], int_bytes[1]]))) +} + +#[inline] +fn consume_header_section_size(input: &[u8]) -> Result<(&[u8], Vec), ()> { + // 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(()); + } + let byte_size = (num_sections * 2) as usize; + if input.len() < byte_size { + return Err(()); + } + let mut sizes = Vec::with_capacity(num_sections as usize); + 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(()); + } + sizes.push(code_size); + } + + Ok((&input[byte_size..], sizes)) +} + impl Header { /// Create new EOF Header. pub fn new( @@ -28,4 +78,91 @@ impl Header { data_size, } } + + pub fn decode(input: &mut [u8]) -> Result { + let mut header = Header::default(); + + // magic 2 bytes 0xEF00 EOF prefix + let (input, kind) = consume_u16(input)?; + if kind != 0xEF00 { + return Err(()); + } + + // version 1 byte 0x01 EOF version + let (input, version) = consume_u8(input)?; + if version != 0x01 { + return Err(()); + } + + // 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(()); + } + + // 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; + + // 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(()); + } + + // code_sections_sizes + let (input, code_sizes) = consume_header_section_size(input)?; + header.code_sizes = code_sizes; + + let (input, kind_container_or_data) = consume_u8(input)?; + + let input = match kind_container_or_data { + KIND_CONTAINER => { + // container_sections_sizes + let (input, container_sizes) = consume_header_section_size(input)?; + header.container_sizes = container_sizes; + input + } + KIND_DATA => input, + _ => return Err(()), + }; + + // 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 header + let (_, terminator) = consume_u8(input)?; + if terminator != KIND_TERMINAL { + return Err(()); + } + + Ok(header) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::hex; + + #[test] + fn sanity_header_decode() { + let mut input = hex!("ef000101000402000100010400000000800000fe"); + let header = Header::decode(&mut 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 mut input = hex!("ef0001010004"); + assert_eq!(Header::decode(&mut input), Err(())); + } } diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 2d1da60808..332a3c905e 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -13,6 +13,8 @@ mod bytecode; mod constants; pub mod db; pub mod env; +pub mod eof; + #[cfg(feature = "c-kzg")] pub mod kzg; pub mod precompile; From fabdc1ba470e2c8bb665797fcf8e20fc3a37f30b Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 15 Feb 2024 03:29:12 +0100 Subject: [PATCH 03/54] EofBody decode --- crates/primitives/src/eof.rs | 37 +++++- crates/primitives/src/eof/body.rs | 55 ++++++++ crates/primitives/src/eof/container.rs | 1 + crates/primitives/src/eof/decode_helpers.rs | 17 +++ crates/primitives/src/eof/header.rs | 131 +++++++++++++------- crates/primitives/src/eof/types_section.rs | 36 ++++++ 6 files changed, 230 insertions(+), 47 deletions(-) create mode 100644 crates/primitives/src/eof/decode_helpers.rs create mode 100644 crates/primitives/src/eof/types_section.rs diff --git a/crates/primitives/src/eof.rs b/crates/primitives/src/eof.rs index 5321b9b25e..5c162f3bfd 100644 --- a/crates/primitives/src/eof.rs +++ b/crates/primitives/src/eof.rs @@ -1,3 +1,34 @@ -pub mod header; -pub mod body; -pub mod container; \ No newline at end of file +mod body; +mod container; +mod decode_helpers; +mod header; +mod types_section; + +use alloy_primitives::Bytes; +pub use body::EofBody; +pub use header::EofHeader; +pub use types_section::TypesSection; + +pub struct Eof { + pub header: EofHeader, + pub body: EofBody, + pub raw: Option, +} + +impl Eof { + pub fn decode(raw: Bytes) -> Result { + let (header, _) = EofHeader::decode(&raw)?; + let body = EofBody::decode(&raw, &header)?; + Ok(Self { + header, + body, + raw: Some(raw), + }) + } + + pub fn push_aux_data(&mut self, _aux_data: Bytes) { + // Need to modify/replace raw Bytes, and recalculate body sections. + // We can be little wasteful here and just replace the raw Bytes and + // data section in the body. Other sections would still pin old raw Bytes. + } +} diff --git a/crates/primitives/src/eof/body.rs b/crates/primitives/src/eof/body.rs index e69de29bb2..4ebe149de1 100644 --- a/crates/primitives/src/eof/body.rs +++ b/crates/primitives/src/eof/body.rs @@ -0,0 +1,55 @@ +use crate::Bytes; + +use super::{EofHeader, TypesSection}; + +#[derive(Default, Clone, Debug)] +pub struct EofBody { + types_section: Vec, + code_section: Vec, + container_section: Vec, + data_section: Bytes, + is_full_data: bool, +} + +impl EofBody { + pub fn decode(input: &Bytes, header: &EofHeader) -> Result { + let header_len = header.len(); + let partial_body_len = header.sum_code_sizes + header.sum_container_sizes; + let full_body_len = partial_body_len + header.data_size as usize; + + if input.len() < header_len + partial_body_len { + return Err(()); + } + + if input.len() > header_len + full_body_len { + return Err(()); + } + + let mut body = EofBody::default(); + + let mut types_input = &input[header_len..]; + for _ in 0..header.types_items() { + 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..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..size)); + start += size; + } + + body.data_section = input.slice(start..); + body.is_full_data = body.data_section.len() == header.data_size as usize; + + Ok(body) + } +} diff --git a/crates/primitives/src/eof/container.rs b/crates/primitives/src/eof/container.rs index e69de29bb2..8b13789179 100644 --- a/crates/primitives/src/eof/container.rs +++ b/crates/primitives/src/eof/container.rs @@ -0,0 +1 @@ + diff --git a/crates/primitives/src/eof/decode_helpers.rs b/crates/primitives/src/eof/decode_helpers.rs new file mode 100644 index 0000000000..6ab139255a --- /dev/null +++ b/crates/primitives/src/eof/decode_helpers.rs @@ -0,0 +1,17 @@ +#[inline] +pub(crate) fn consume_u8(input: &[u8]) -> Result<(&[u8], u8), ()> { + if input.is_empty() { + return Err(()); + } + Ok((&input[1..], input[0])) +} + +/// Consumes a u16 from the input. +#[inline] +pub(crate) fn consume_u16(input: &[u8]) -> Result<(&[u8], u16), ()> { + if input.len() < 2 { + return Err(()); + } + 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/eof/header.rs b/crates/primitives/src/eof/header.rs index 737dc37f0b..6749fb34d7 100644 --- a/crates/primitives/src/eof/header.rs +++ b/crates/primitives/src/eof/header.rs @@ -1,6 +1,8 @@ +use super::decode_helpers::{consume_u16, consume_u8}; + /// EOF Header containing #[derive(Clone, Debug, Default, PartialEq, Eq)] -pub struct Header { +pub struct EofHeader { /// Size of EOF types section. /// types section includes num of input and outputs and max stack size. pub types_size: u16, @@ -12,6 +14,10 @@ pub struct Header { 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; @@ -21,24 +27,7 @@ const KIND_CONTAINER: u8 = 3; const KIND_DATA: u8 = 4; #[inline] -fn consume_u8(input: &[u8]) -> Result<(&[u8], u8), ()> { - if input.is_empty() { - return Err(()); - } - Ok((&input[1..], input[0])) -} - -#[inline] -fn consume_u16(input: &[u8]) -> Result<(&[u8], u16), ()> { - if input.len() < 2 { - return Err(()); - } - let (int_bytes, rest) = input.split_at(2); - Ok((rest, u16::from_be_bytes([int_bytes[0], int_bytes[1]]))) -} - -#[inline] -fn consume_header_section_size(input: &[u8]) -> Result<(&[u8], Vec), ()> { +fn consume_header_section_size(input: &[u8]) -> Result<(&[u8], Vec, usize), ()> { // 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)?; @@ -50,6 +39,7 @@ fn consume_header_section_size(input: &[u8]) -> Result<(&[u8], Vec), ()> { return Err(()); } 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 @@ -57,30 +47,51 @@ fn consume_header_section_size(input: &[u8]) -> Result<(&[u8], Vec), ()> { if code_size == 0 { return Err(()); } + sum += code_size as usize; sizes.push(code_size); } - Ok((&input[byte_size..], sizes)) + Ok((&input[byte_size..], sizes, sum)) } -impl Header { - /// Create new EOF Header. - pub fn new( - types_size: u16, - code_sizes: Vec, - container_sizes: Vec, - data_size: u16, - ) -> Self { - Self { - types_size, - code_sizes, - container_sizes, - data_size, - } +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 len(&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 } - pub fn decode(input: &mut [u8]) -> Result { - let mut header = Header::default(); + pub fn types_items(&self) -> usize { + self.types_size as usize / 4 + } + + pub fn body_len(&self) -> usize { + self.sum_code_sizes + self.sum_container_sizes + self.data_size as usize + } + + pub fn eof_len(&self) -> usize { + self.len() + self.body_len() + } + + pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), ()> { + let mut header = EofHeader::default(); // magic 2 bytes 0xEF00 EOF prefix let (input, kind) = consume_u16(input)?; @@ -112,16 +123,18 @@ impl Header { } // code_sections_sizes - let (input, code_sizes) = consume_header_section_size(input)?; - header.code_sizes = code_sizes; + let (input, sizes, sum) = consume_header_section_size(input)?; + 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, container_sizes) = consume_header_section_size(input)?; - header.container_sizes = container_sizes; + let (input, sizes, sum) = consume_header_section_size(input)?; + header.container_sizes = sizes; + header.sum_container_sizes = sum; input } KIND_DATA => input, @@ -135,13 +148,43 @@ impl Header { let (input, data_size) = consume_u16(input)?; header.data_size = data_size; - // terminator 1 byte 0x00 marks the end of the header + // terminator 1 byte 0x00 marks the end of the EofHeader let (_, terminator) = consume_u8(input)?; if terminator != KIND_TERMINAL { return Err(()); } - Ok(header) + Ok((header, input)) + } + + pub fn validate(&self) -> Result<(), ()> { + // minimum valid header size is 15 bytes (Checked in decode) + // version must be 0x01 (Checked in decode) + + // types_size is divisible by 4 + if self.types_size % 4 != 0 { + return Err(()); + } + + // the number of code sections must be equal to types_size / 4 + if self.code_sizes.len() != self.types_size as usize / 4 { + return Err(()); + } + // the number of code sections must not exceed 1024 + if self.code_sizes.len() > 1024 { + return Err(()); + } + // code_size may not be 0 + if self.code_sizes.is_empty() { + return Err(()); + } + // the number of container sections must not exceed 256 + if self.container_sizes.len() > 256 { + return Err(()); + } + // container_size may not be 0, but container sections are optional + // (Checked in decode) + Ok(()) } } @@ -153,7 +196,7 @@ mod tests { #[test] fn sanity_header_decode() { let mut input = hex!("ef000101000402000100010400000000800000fe"); - let header = Header::decode(&mut input).unwrap(); + let (header, _) = EofHeader::decode(&mut input).unwrap(); assert_eq!(header.types_size, 4); assert_eq!(header.code_sizes, vec![1]); assert_eq!(header.container_sizes, vec![]); @@ -163,6 +206,6 @@ mod tests { #[test] fn decode_header_not_terminated() { let mut input = hex!("ef0001010004"); - assert_eq!(Header::decode(&mut input), Err(())); + assert_eq!(EofHeader::decode(&mut input), Err(())); } } diff --git a/crates/primitives/src/eof/types_section.rs b/crates/primitives/src/eof/types_section.rs new file mode 100644 index 0000000000..d1da18711c --- /dev/null +++ b/crates/primitives/src/eof/types_section.rs @@ -0,0 +1,36 @@ +use super::decode_helpers::{consume_u16, consume_u8}; + +#[derive(Debug, Clone, Default, PartialEq, Eq, Copy)] +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 { + #[inline] + pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), ()> { + 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)) + } + + pub fn validate(&self) -> Result<(), ()> { + if self.inputs <= 0x7f || self.outputs <= 0x80 || self.max_stack_size <= 0x03FF { + return Err(()); + } + Ok(()) + } +} From 2ff0f28077ffb644fbd1f485bc4c8fa7c7c3284d Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 18 Feb 2024 18:30:40 +0100 Subject: [PATCH 04/54] disable eof deprecated opcodes --- Cargo.lock | 4 ++-- crates/interpreter/src/instruction_result.rs | 7 ++++++- .../interpreter/src/instructions/control.rs | 13 ++++++++++++- crates/interpreter/src/instructions/host.rs | 19 ++++++++++++++----- crates/interpreter/src/instructions/macros.rs | 11 ++++++++++- crates/interpreter/src/instructions/opcode.rs | 3 ++- crates/interpreter/src/instructions/system.rs | 3 +++ crates/interpreter/src/interpreter.rs | 5 ++++- crates/precompile/src/lib.rs | 2 +- crates/primitives/src/eof.rs | 2 +- crates/primitives/src/eof/body.rs | 4 ++-- crates/primitives/src/eof/container.rs | 1 - crates/primitives/src/specification.rs | 13 +++++++++++-- crates/revm/benches/bench.rs | 3 ++- crates/revm/src/context.rs | 7 +++++-- 15 files changed, 75 insertions(+), 22 deletions(-) delete mode 100644 crates/primitives/src/eof/container.rs diff --git a/Cargo.lock b/Cargo.lock index 29a03cd699..759ac8fe17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,9 +46,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "alloy-primitives" -version = "0.6.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef197eb250c64962003cb08b90b17f0882c192f4a6f2f544809d424fd7cb0e7d" +checksum = "f4b6fb2b432ff223d513db7f908937f63c252bee0af9b82bfd25b0a5dd1eb0d8" dependencies = [ "alloy-rlp", "arbitrary", diff --git a/crates/interpreter/src/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index 13e250ee3d..9a5ef22cbe 100644 --- a/crates/interpreter/src/instruction_result.rs +++ b/crates/interpreter/src/instruction_result.rs @@ -44,9 +44,11 @@ pub enum InstructionResult { CreateContractStartingWithEF, /// EIP-3860: Limit and meter initcode. Initcode size limit exceeded. CreateInitCodeSizeLimit, - + /* External error */ /// Fatal external error. Returned by database. FatalExternalError, + /* EOF */ + OpcodeDisabledInEof, } impl From for InstructionResult { @@ -135,6 +137,7 @@ macro_rules! return_error { | InstructionResult::CreateContractStartingWithEF | InstructionResult::CreateInitCodeSizeLimit | InstructionResult::FatalExternalError + | InstructionResult::OpcodeDisabledInEof }; } @@ -255,6 +258,8 @@ impl From for SuccessOrHalt { Self::Halt(HaltReason::CreateInitCodeSizeLimit) } InstructionResult::FatalExternalError => Self::FatalExternalError, + // TODO(EOF) Check how to propagate error that should be a EVM panic! + InstructionResult::OpcodeDisabledInEof => Self::FatalExternalError, } } } diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index 05da0a7cf8..1c643d51f0 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -6,7 +6,16 @@ use crate::{ Host, InstructionResult, Interpreter, InterpreterResult, }; +pub fn rjump(interpreter: &mut Interpreter, _host: &mut H) { + gas!(interpreter, gas::BASE); +} + +pub fn rjumpi(interpreter: &mut Interpreter, _host: &mut H) {} + +pub fn rjumpv(interpreter: &mut Interpreter, _host: &mut H) {} + pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { + panic_on_eof!(interpreter); gas!(interpreter, gas::MID); pop!(interpreter, dest); let dest = as_usize_or_fail!(interpreter, dest, InstructionResult::InvalidJump); @@ -21,6 +30,7 @@ pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { } pub fn jumpi(interpreter: &mut Interpreter, _host: &mut H) { + panic_on_eof!(interpreter); gas!(interpreter, gas::HIGH); pop!(interpreter, dest, value); if value != U256::ZERO { @@ -36,11 +46,12 @@ pub fn jumpi(interpreter: &mut Interpreter, _host: &mut H) { } } -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 pc(interpreter: &mut Interpreter, _host: &mut H) { + panic_on_eof!(interpreter); gas!(interpreter, gas::BASE); // - 1 because we have already advanced the instruction pointer in `Interpreter::step` push!(interpreter, U256::from(interpreter.program_counter() - 1)); diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index 4919b644a6..dae48440cf 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -45,6 +45,7 @@ pub fn selfbalance(interpreter: &mut Interpreter, host: &mu } pub fn extcodesize(interpreter: &mut Interpreter, host: &mut H) { + panic_on_eof!(interpreter); pop_address!(interpreter, address); let Some((code, is_cold)) = host.code(address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; @@ -70,6 +71,7 @@ pub fn extcodesize(interpreter: &mut Interpreter, host: &mu /// EIP-1052: EXTCODEHASH opcode pub fn extcodehash(interpreter: &mut Interpreter, host: &mut H) { + panic_on_eof!(interpreter); check!(interpreter, CONSTANTINOPLE); pop_address!(interpreter, address); let Some((code_hash, is_cold)) = host.code_hash(address) else { @@ -94,6 +96,7 @@ pub fn extcodehash(interpreter: &mut Interpreter, host: &mu } pub fn extcodecopy(interpreter: &mut Interpreter, host: &mut H) { + panic_on_eof!(interpreter); pop_address!(interpreter, address); pop!(interpreter, memory_offset, code_offset, len_u256); @@ -151,7 +154,7 @@ pub fn sload(interpreter: &mut Interpreter, host: &mut H) { } pub fn sstore(interpreter: &mut Interpreter, host: &mut H) { - check_staticcall!(interpreter); + error_on_static_call!(interpreter); pop!(interpreter, index, value); let Some((original, old, new, is_cold)) = @@ -171,7 +174,7 @@ pub fn sstore(interpreter: &mut Interpreter, host: &mut H) /// 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); @@ -191,7 +194,7 @@ pub fn tload(interpreter: &mut Interpreter, host: &mut H) { } 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); @@ -224,7 +227,8 @@ pub fn log(interpreter: &mut Interpreter, host: &mut H) } pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut H) { - check_staticcall!(interpreter); + panic_on_eof!(interpreter); + error_on_static_call!(interpreter); pop_address!(interpreter, target); let Some(res) = host.selfdestruct(interpreter.contract.address, target) else { @@ -245,7 +249,8 @@ pub fn create( interpreter: &mut Interpreter, host: &mut H, ) { - check_staticcall!(interpreter); + panic_on_eof!(interpreter); + error_on_static_call!(interpreter); // EIP-1014: Skinny CREATE2 if IS_CREATE2 { @@ -311,6 +316,7 @@ pub fn create( } pub fn call(interpreter: &mut Interpreter, host: &mut H) { + panic_on_eof!(interpreter); pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); // max gas limit is not possible in real ethereum situation. @@ -371,6 +377,7 @@ pub fn call(interpreter: &mut Interpreter, host: &mut H) { } pub fn call_code(interpreter: &mut Interpreter, host: &mut H) { + panic_on_eof!(interpreter); pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); // max gas limit is not possible in real ethereum situation. @@ -426,6 +433,7 @@ pub fn call_code(interpreter: &mut Interpreter, host: &mut } pub fn delegate_call(interpreter: &mut Interpreter, host: &mut H) { + panic_on_eof!(interpreter); check!(interpreter, HOMESTEAD); pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); @@ -472,6 +480,7 @@ pub fn delegate_call(interpreter: &mut Interpreter, host: & } pub fn static_call(interpreter: &mut Interpreter, host: &mut H) { + panic_on_eof!(interpreter); check!(interpreter, BYZANTIUM); pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index ec6e6cb775..dc2ac0c9a3 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -1,4 +1,4 @@ -macro_rules! check_staticcall { +macro_rules! error_on_static_call { ($interp:expr) => { if $interp.is_static { $interp.instruction_result = InstructionResult::StateChangeDuringStaticCall; @@ -7,6 +7,15 @@ macro_rules! check_staticcall { }; } +macro_rules! panic_on_eof { + ($interp:expr) => { + if $interp.is_static { + $interp.instruction_result = InstructionResult::OpcodeDisabledInEof; + return; + } + }; +} + macro_rules! check { ($interp:expr, $min:ident) => { // TODO: Force const-eval on the condition with a `const {}` block once they are stable diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index 79a77ee829..54a27b155b 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -185,7 +185,7 @@ opcodes! { 0x58 => PC => control::pc, 0x59 => MSIZE => memory::msize, 0x5A => GAS => system::gas, - 0x5B => JUMPDEST => control::jumpdest, + 0x5B => JUMPDEST => control::jumpdest_or_nop, 0x5C => TLOAD => host::tload::, 0x5D => TSTORE => host::tstore::, 0x5E => MCOPY => memory::mcopy::, @@ -900,6 +900,7 @@ pub const fn spec_opcode_gas(spec_id: SpecId) -> &'static [OpInfo; 256] { MERGE, SHANGHAI, CANCUN, + PRAGUE, LATEST, ) } diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index 07df7a6604..c76a101beb 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -30,11 +30,13 @@ pub fn caller(interpreter: &mut Interpreter, _host: &mut H) { } pub fn codesize(interpreter: &mut Interpreter, _host: &mut H) { + panic_on_eof!(interpreter); gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.contract.bytecode.len())); } pub fn codecopy(interpreter: &mut Interpreter, _host: &mut H) { + panic_on_eof!(interpreter); 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)); @@ -133,6 +135,7 @@ pub fn returndatacopy(interpreter: &mut Interpreter, _host: } pub fn gas(interpreter: &mut Interpreter, _host: &mut H) { + panic_on_eof!(interpreter); 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 4cddf3ca6d..a9e8e84d8a 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -45,6 +45,8 @@ pub struct Interpreter { pub return_data_buffer: Bytes, /// Whether the interpreter is in "staticcall" mode, meaning no state changes can happen. pub is_static: bool, + /// Whether we are Interpreting the Ethereum Object Format (EOF) bytecode. + pub is_eof: bool, /// Actions that the EVM should do. /// /// Set inside CALL or CREATE instructions and RETURN or REVERT instructions. Additionally those instructions will set @@ -116,13 +118,14 @@ impl InterpreterAction { impl Interpreter { /// Create new interpreter - pub fn new(contract: Box, gas_limit: u64, is_static: bool) -> Self { + pub fn new(contract: Box, gas_limit: u64, is_static: bool, is_eof: bool) -> Self { Self { instruction_pointer: contract.bytecode.as_ptr(), contract, gas: Gas::new(gas_limit), instruction_result: InstructionResult::Continue, is_static, + is_eof, return_data_buffer: Bytes::new(), shared_memory: EMPTY_SHARED_MEMORY, stack: Stack::new(), diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index 9a099f7885..be064dcc31 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -254,7 +254,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/eof.rs b/crates/primitives/src/eof.rs index 5c162f3bfd..519ef2ee33 100644 --- a/crates/primitives/src/eof.rs +++ b/crates/primitives/src/eof.rs @@ -1,5 +1,4 @@ mod body; -mod container; mod decode_helpers; mod header; mod types_section; @@ -26,6 +25,7 @@ impl Eof { }) } + /// TODO implement it. pub fn push_aux_data(&mut self, _aux_data: Bytes) { // Need to modify/replace raw Bytes, and recalculate body sections. // We can be little wasteful here and just replace the raw Bytes and diff --git a/crates/primitives/src/eof/body.rs b/crates/primitives/src/eof/body.rs index 4ebe149de1..e08e5f26d6 100644 --- a/crates/primitives/src/eof/body.rs +++ b/crates/primitives/src/eof/body.rs @@ -8,7 +8,7 @@ pub struct EofBody { code_section: Vec, container_section: Vec, data_section: Bytes, - is_full_data: bool, + is_data_filled: bool, } impl EofBody { @@ -48,7 +48,7 @@ impl EofBody { } body.data_section = input.slice(start..); - body.is_full_data = body.data_section.len() == header.data_size as usize; + body.is_data_filled = body.data_section.len() == header.data_size as usize; Ok(body) } diff --git a/crates/primitives/src/eof/container.rs b/crates/primitives/src/eof/container.rs deleted file mode 100644 index 8b13789179..0000000000 --- a/crates/primitives/src/eof/container.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index 937acc141f..26c4ddbc2e 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -26,8 +26,9 @@ pub enum SpecId { 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 TBD + SHANGHAI = 16, // Shanghai 17034870 (Timestamp: 1681338455) + CANCUN = 17, // Cancun TBD (Timestamp: 1710338135) + PRAGUE = 18, // Praque TBD LATEST = u8::MAX, } @@ -61,6 +62,7 @@ pub enum SpecId { CANYON = 19, CANCUN = 20, ECOTONE = 21, + PRAGUE = 22, LATEST = u8::MAX, } @@ -97,6 +99,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")] @@ -150,6 +153,7 @@ spec!(LONDON, LondonSpec); spec!(MERGE, MergeSpec); spec!(SHANGHAI, ShanghaiSpec); spec!(CANCUN, CancunSpec); +spec!(PRAGUE, PragueSpec); spec!(LATEST, LatestSpec); @@ -222,6 +226,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; @@ -278,6 +286,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/revm/benches/bench.rs b/crates/revm/benches/bench.rs index 73253cbae9..e7bc5f3681 100644 --- a/crates/revm/benches/bench.rs +++ b/crates/revm/benches/bench.rs @@ -114,7 +114,8 @@ fn bench_eval(g: &mut BenchmarkGroup<'_, WallTime>, evm: &mut Evm<'static, (), B // replace memory with empty memory to use it inside interpreter. // Later return memory back. let temp = core::mem::replace(&mut shared_memory, EMPTY_SHARED_MEMORY); - let mut interpreter = Interpreter::new(Box::new(contract.clone()), u64::MAX, false); + let mut interpreter = + Interpreter::new(Box::new(contract.clone()), u64::MAX, false, false); let res = interpreter.run(temp, &instruction_table, &mut host); shared_memory = interpreter.take_memory(); host.clear(); diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index 1646bc35c1..edc6e19620 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -350,10 +350,12 @@ impl EvmContext { inputs.value, )); + // TODO(eof) flag. + FrameOrResult::new_create_frame( created_address, checkpoint, - Interpreter::new(contract, gas.limit(), false), + Interpreter::new(contract, gas.limit(), false, false), ) } @@ -425,11 +427,12 @@ impl EvmContext { code_hash, &inputs.context, )); + // TODO(eof) flag // Create interpreter and executes call and push new CallStackFrame. FrameOrResult::new_call_frame( inputs.return_memory_offset.clone(), checkpoint, - Interpreter::new(contract, gas.limit(), inputs.is_static), + Interpreter::new(contract, gas.limit(), inputs.is_static, false), ) } else { self.journaled_state.checkpoint_commit(); From 20fcdaf411260e48a42c830bfb2c2ebf4e93516d Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 20 Feb 2024 11:42:30 +0100 Subject: [PATCH 05/54] add eof instructions --- crates/interpreter/src/instructions.rs | 3 +- .../interpreter/src/instructions/contract.rs | 307 ++++++++++++++++++ .../{host => contract}/call_helpers.rs | 0 .../interpreter/src/instructions/control.rs | 6 + crates/interpreter/src/instructions/data.rs | 16 + crates/interpreter/src/instructions/host.rs | 285 ---------------- crates/interpreter/src/instructions/opcode.rs | 46 +-- crates/interpreter/src/instructions/stack.rs | 6 + crates/interpreter/src/instructions/system.rs | 2 + .../interpreter/src/interpreter/analysis.rs | 4 +- crates/primitives/src/bytecode.rs | 37 +-- crates/primitives/src/{ => bytecode}/eof.rs | 0 .../primitives/src/{ => bytecode}/eof/body.rs | 0 .../src/{ => bytecode}/eof/decode_helpers.rs | 0 .../src/{ => bytecode}/eof/header.rs | 0 .../src/{ => bytecode}/eof/types_section.rs | 0 crates/primitives/src/bytecode/legacy.rs | 3 + .../src/bytecode/legacy/jump_map.rs | 40 +++ crates/primitives/src/lib.rs | 1 - 19 files changed, 412 insertions(+), 344 deletions(-) create mode 100644 crates/interpreter/src/instructions/contract.rs rename crates/interpreter/src/instructions/{host => contract}/call_helpers.rs (100%) create mode 100644 crates/interpreter/src/instructions/data.rs rename crates/primitives/src/{ => bytecode}/eof.rs (100%) rename crates/primitives/src/{ => bytecode}/eof/body.rs (100%) rename crates/primitives/src/{ => bytecode}/eof/decode_helpers.rs (100%) rename crates/primitives/src/{ => bytecode}/eof/header.rs (100%) rename crates/primitives/src/{ => bytecode}/eof/types_section.rs (100%) create mode 100644 crates/primitives/src/bytecode/legacy.rs create mode 100644 crates/primitives/src/bytecode/legacy/jump_map.rs diff --git a/crates/interpreter/src/instructions.rs b/crates/interpreter/src/instructions.rs index ae56015699..9a588509d1 100644 --- a/crates/interpreter/src/instructions.rs +++ b/crates/interpreter/src/instructions.rs @@ -5,7 +5,9 @@ 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; @@ -13,5 +15,4 @@ pub mod memory; pub mod opcode; pub mod stack; pub mod system; - pub use opcode::{Instruction, OpCode, OPCODE_JUMPMAP}; diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs new file mode 100644 index 0000000000..c61ef8e66d --- /dev/null +++ b/crates/interpreter/src/instructions/contract.rs @@ -0,0 +1,307 @@ +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}, + primitives::{Address, Bytes, Log, LogData, Spec, SpecId::*, B256, U256}, + CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, Host, InstructionResult, + Transfer, MAX_INITCODE_SIZE, +}; +use alloc::{boxed::Box, vec::Vec}; +use core::cmp::min; +use revm_primitives::BLOCK_HASH_HISTORY; + +pub fn create3(interpreter: &mut Interpreter, host: &mut H) {} + +pub fn create4(interpreter: &mut Interpreter, host: &mut H) {} + +pub fn return_contract(interpreter: &mut Interpreter, host: &mut H) {} + +pub fn call2(interpreter: &mut Interpreter, host: &mut H) {} + +pub fn delegate_call2(interpreter: &mut Interpreter, host: &mut H) {} + +pub fn static_call2(interpreter: &mut Interpreter, host: &mut H) {} + +pub fn create( + interpreter: &mut Interpreter, + host: &mut H, +) { + panic_on_eof!(interpreter); + 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); + shared_memory_resize!(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)); + 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) { + panic_on_eof!(interpreter); + 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) { + panic_on_eof!(interpreter); + 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) { + panic_on_eof!(interpreter); + 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) { + panic_on_eof!(interpreter); + 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/call_helpers.rs b/crates/interpreter/src/instructions/contract/call_helpers.rs similarity index 100% rename from crates/interpreter/src/instructions/host/call_helpers.rs rename to crates/interpreter/src/instructions/contract/call_helpers.rs diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index 1c643d51f0..f8b79edeeb 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -50,6 +50,12 @@ pub fn jumpdest_or_nop(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::JUMPDEST); } +pub fn callf(interpreter: &mut Interpreter, _host: &mut H) {} + +pub fn retf(interpreter: &mut Interpreter, _host: &mut H) {} + +pub fn jumpf(interpreter: &mut Interpreter, _host: &mut H) {} + pub fn pc(interpreter: &mut Interpreter, _host: &mut H) { panic_on_eof!(interpreter); gas!(interpreter, gas::BASE); diff --git a/crates/interpreter/src/instructions/data.rs b/crates/interpreter/src/instructions/data.rs new file mode 100644 index 0000000000..dc4876d155 --- /dev/null +++ b/crates/interpreter/src/instructions/data.rs @@ -0,0 +1,16 @@ +use crate::{ + gas::{self, COLD_ACCOUNT_ACCESS_COST, WARM_STORAGE_READ_COST}, + interpreter::{Interpreter, InterpreterAction}, + primitives::{Address, Bytes, Log, LogData, Spec, SpecId::*, B256, U256}, + CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, Host, InstructionResult, + Transfer, MAX_INITCODE_SIZE, +}; +use alloc::{boxed::Box, vec::Vec}; + +pub fn data_load(interpreter: &mut Interpreter, host: &mut H) {} + +pub fn data_loadn(interpreter: &mut Interpreter, host: &mut H) {} + +pub fn data_size(interpreter: &mut Interpreter, host: &mut H) {} + +pub fn data_copy(interpreter: &mut Interpreter, host: &mut H) {} diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index dae48440cf..db0fbd091c 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -1,7 +1,3 @@ -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}, @@ -244,284 +240,3 @@ pub fn selfdestruct(interpreter: &mut Interpreter, host: &m interpreter.instruction_result = InstructionResult::SelfDestruct; } - -pub fn create( - interpreter: &mut Interpreter, - host: &mut H, -) { - panic_on_eof!(interpreter); - 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); - shared_memory_resize!(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)); - 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) { - panic_on_eof!(interpreter); - 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) { - panic_on_eof!(interpreter); - 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) { - panic_on_eof!(interpreter); - 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) { - panic_on_eof!(interpreter); - 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/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index 54a27b155b..6753d2b1e8 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -306,10 +306,10 @@ opcodes! { // 0xCD // 0xCE // 0xCF - // 0xD0 - // 0xD1 - // 0xD2 - // 0xD3 + 0xD0 => DATALOAD => data::data_load, + 0xD1 => DATALOADN => data::data_loadn, + 0xD2 => DATASIZE => data::data_size, + 0xD3 => DATACOPY => data::data_copy, // 0xD4 // 0xD5 // 0xD6 @@ -322,33 +322,33 @@ opcodes! { // 0xDD // 0xDE // 0xDF - // 0xE0 - // 0xE1 - // 0xE2 - // 0xE3 - // 0xE4 - // 0xE5 - // 0xE6 - // 0xE7 - // 0xE8 + 0xE0 => RJUMP => control::rjump, + 0xE1 => RJUMPI => control::rjumpi, + 0xE2 => RJUMPV => control::rjumpv, + 0xE3 => CALLF => control::callf, + 0xE4 => RETF => control::retf, + 0xE5 => JUMPF => control::jumpf, + 0xE6 => DUPN => stack::dupn, + 0xE7 => SWAPN => stack::swapn, + 0xE8 => EXCHANGE => stack::exchange, // 0xE9 // 0xEA // 0xEB - // 0xEC - // 0xED - // 0xEE + 0xEC => CRATE3 => contract::create3::, + 0xED => CREATE4 => contract::create4::, + 0xEE => RETURNCONTRACT => contract::return_contract::, // 0xEF - 0xF0 => CREATE => host::create::, - 0xF1 => CALL => host::call::, - 0xF2 => CALLCODE => host::call_code::, + 0xF0 => CREATE => contract::create::, + 0xF1 => CALL => contract::call::, + 0xF2 => CALLCODE => contract::call_code::, 0xF3 => RETURN => control::ret, - 0xF4 => DELEGATECALL => host::delegate_call::, - 0xF5 => CREATE2 => host::create::, + 0xF4 => DELEGATECALL => contract::delegate_call::, + 0xF5 => CREATE2 => contract::create::, // 0xF6 - // 0xF7 + 0xF7 => RETURNDATALOAD => system::returndataload::, // 0xF8 // 0xF9 - 0xFA => STATICCALL => host::static_call::, + 0xFA => STATICCALL => contract::static_call::, // 0xFB // 0xFC 0xFD => REVERT => control::revert::, diff --git a/crates/interpreter/src/instructions/stack.rs b/crates/interpreter/src/instructions/stack.rs index 6913116330..3c35c24296 100644 --- a/crates/interpreter/src/instructions/stack.rs +++ b/crates/interpreter/src/instructions/stack.rs @@ -50,3 +50,9 @@ pub fn swap(interpreter: &mut Interpreter, _host: &mut interpreter.instruction_result = result; } } + +pub fn dupn(interpreter: &mut Interpreter, _host: &mut H) {} + +pub fn swapn(interpreter: &mut Interpreter, _host: &mut H) {} + +pub fn exchange(interpreter: &mut Interpreter, _host: &mut H) {} diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index c76a101beb..10339d8b72 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -134,6 +134,8 @@ pub fn returndatacopy(interpreter: &mut Interpreter, _host: } } +pub fn returndataload(interpreter: &mut Interpreter, _host: &mut H) {} + pub fn gas(interpreter: &mut Interpreter, _host: &mut H) { panic_on_eof!(interpreter); gas!(interpreter, gas::BASE); diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index eda7216412..1b2d646591 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -1,7 +1,9 @@ use crate::opcode; use crate::primitives::{ bitvec::prelude::{bitvec, BitVec, Lsb0}, - keccak256, Bytecode, BytecodeState, Bytes, JumpMap, B256, KECCAK_EMPTY, + keccak256, + legacy::JumpMap, + Bytecode, BytecodeState, Bytes, B256, KECCAK_EMPTY, }; use alloc::sync::Arc; use core::fmt; diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index bbf8791eef..5e0a3adb19 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -1,3 +1,6 @@ +pub mod eof; +pub mod legacy; + use crate::{hex, keccak256, Bytes, B256, KECCAK_EMPTY}; use alloc::{sync::Arc, vec::Vec}; use bitvec::{ @@ -5,39 +8,7 @@ use bitvec::{ vec::BitVec, }; use core::fmt::Debug; - -/// 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>); - -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() - } - - /// 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 legacy::JumpMap; /// State of the [`Bytecode`] analysis. #[derive(Clone, Debug, PartialEq, Eq, Hash)] diff --git a/crates/primitives/src/eof.rs b/crates/primitives/src/bytecode/eof.rs similarity index 100% rename from crates/primitives/src/eof.rs rename to crates/primitives/src/bytecode/eof.rs diff --git a/crates/primitives/src/eof/body.rs b/crates/primitives/src/bytecode/eof/body.rs similarity index 100% rename from crates/primitives/src/eof/body.rs rename to crates/primitives/src/bytecode/eof/body.rs diff --git a/crates/primitives/src/eof/decode_helpers.rs b/crates/primitives/src/bytecode/eof/decode_helpers.rs similarity index 100% rename from crates/primitives/src/eof/decode_helpers.rs rename to crates/primitives/src/bytecode/eof/decode_helpers.rs diff --git a/crates/primitives/src/eof/header.rs b/crates/primitives/src/bytecode/eof/header.rs similarity index 100% rename from crates/primitives/src/eof/header.rs rename to crates/primitives/src/bytecode/eof/header.rs diff --git a/crates/primitives/src/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs similarity index 100% rename from crates/primitives/src/eof/types_section.rs rename to crates/primitives/src/bytecode/eof/types_section.rs diff --git a/crates/primitives/src/bytecode/legacy.rs b/crates/primitives/src/bytecode/legacy.rs new file mode 100644 index 0000000000..189a00267e --- /dev/null +++ b/crates/primitives/src/bytecode/legacy.rs @@ -0,0 +1,3 @@ +mod jump_map; + +pub use jump_map::JumpMap; 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..8f46d09d27 --- /dev/null +++ b/crates/primitives/src/bytecode/legacy/jump_map.rs @@ -0,0 +1,40 @@ +use crate::{hex, keccak256, Bytes, B256, KECCAK_EMPTY}; +use alloc::{sync::Arc, vec::Vec}; +use bitvec::{ + prelude::{bitvec, Lsb0}, + vec::BitVec, +}; +use core::fmt::Debug; + +/// 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>); + +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() + } + + /// Construct a jumpa 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/lib.rs b/crates/primitives/src/lib.rs index 332a3c905e..eb70e0f71a 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -13,7 +13,6 @@ mod bytecode; mod constants; pub mod db; pub mod env; -pub mod eof; #[cfg(feature = "c-kzg")] pub mod kzg; From 22bf551cfbbda645b0623cd37844c3789f1fb505 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 20 Feb 2024 15:40:20 +0100 Subject: [PATCH 06/54] temp tests --- .../interpreter/src/instructions/control.rs | 16 +++++++++++++ crates/interpreter/src/interpreter.rs | 24 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index f8b79edeeb..f037407e9f 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -8,6 +8,11 @@ use crate::{ pub fn rjump(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); + let offset = 0; + // 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.byte_offset(offset + 2) }; } pub fn rjumpi(interpreter: &mut Interpreter, _host: &mut H) {} @@ -111,3 +116,14 @@ 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 super::*; + use crate::{opcode::RJUMP, Interpreter}; + + #[test] + fn sanity_rjump() { + let interp = Interpreter::new_bytecode(Bytes::from([RJUMP, 0x00, 0x00])); + } +} diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index a9e8e84d8a..96c3d2ce00 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -54,6 +54,12 @@ pub struct Interpreter { pub next_action: InterpreterAction, } +impl Default for Interpreter { + fn default() -> Self { + Self::new(Box::new(Contract::default()), 0, false, false) + } +} + /// The result of an interpreter operation. #[derive(Debug, Clone, PartialEq, Eq)] pub struct InterpreterResult { @@ -133,6 +139,24 @@ impl Interpreter { } } + /// Test related helper + #[cfg(test)] + pub fn new_bytecode(bytecode: Bytes) -> Self { + Self::new( + Box::new(Contract::new( + Bytes::new(), + crate::primitives::Bytecode::new_raw(bytecode), + crate::primitives::B256::default(), + crate::primitives::Address::default(), + crate::primitives::Address::default(), + U256::ZERO, + )), + 0, + false, + false, + ) + } + /// 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 From 33974b394f84319ebafb9e408989a85015c09835 Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 22 Feb 2024 18:52:41 +0100 Subject: [PATCH 07/54] rjump instructions --- crates/interpreter/src/gas/constants.rs | 1 + .../interpreter/src/instructions/contract.rs | 2 +- .../interpreter/src/instructions/control.rs | 53 +++++++++++++++++-- crates/interpreter/src/instructions/macros.rs | 8 +++ crates/primitives/src/bytecode.rs | 2 +- .../src/bytecode/legacy/jump_map.rs | 2 +- 6 files changed, 60 insertions(+), 8 deletions(-) diff --git a/crates/interpreter/src/gas/constants.rs b/crates/interpreter/src/gas/constants.rs index ed3c7aa38a..2354b715ff 100644 --- a/crates/interpreter/src/gas/constants.rs +++ b/crates/interpreter/src/gas/constants.rs @@ -1,6 +1,7 @@ pub const ZERO: u64 = 0; pub const BASE: u64 = 2; pub const VERYLOW: u64 = 3; +pub const CONDITION_JUMP_GAS: u64 = 4; pub const LOW: u64 = 5; pub const MID: u64 = 8; pub const HIGH: u64 = 10; diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index e301c20799..4517d8f45c 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -9,9 +9,9 @@ use crate::{ CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, Host, InstructionResult, Transfer, MAX_INITCODE_SIZE, }; -use std::{boxed::Box, vec::Vec}; use core::cmp::min; use revm_primitives::BLOCK_HASH_HISTORY; +use std::{boxed::Box, vec::Vec}; pub fn create3(interpreter: &mut Interpreter, host: &mut H) {} diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index f037407e9f..b414bead45 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -8,16 +8,50 @@ use crate::{ pub fn rjump(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); - let offset = 0; + let offset = unsafe { *interpreter.instruction_pointer.cast::() } 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) { + 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. - interpreter.instruction_pointer = - unsafe { interpreter.instruction_pointer.byte_offset(offset + 2) }; + let mut offset = 2; + if !condition.is_zero() { + offset += unsafe { *interpreter.instruction_pointer.cast::() } as isize; + } + + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset) }; } -pub fn rjumpi(interpreter: &mut Interpreter, _host: &mut H) {} +pub fn rjumpv(interpreter: &mut Interpreter, _host: &mut H) { + gas!(interpreter, gas::CONDITION_JUMP_GAS); + pop!(interpreter, case); + let case = as_isize_saturated!(case); + + let max_index = interpreter.instruction_pointer.cast::() as isize; + + // In spec it is (max_index+1)*2 but pointer is already incremented in + // `Interpreter::step` so for revm it is max_index*2 for destinations and +1 for max_index. + let mut offset = max_index * 2 + 1; + + if case <= max_index { + offset += unsafe { + interpreter + .instruction_pointer + // offset for max_index that is one byte + .offset(1) + .cast::() + .offset(case) + } as isize; + } -pub fn rjumpv(interpreter: &mut Interpreter, _host: &mut H) {} + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset) }; +} pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { panic_on_eof!(interpreter); @@ -126,4 +160,13 @@ mod test { fn sanity_rjump() { let interp = Interpreter::new_bytecode(Bytes::from([RJUMP, 0x00, 0x00])); } + + #[test] + fn ptr() { + let mut a = [1, 2, 3, 4, 5]; + let ptr = a.as_ptr(); + let ptr = ptr.cast::(); + let slice = unsafe { core::slice::from_raw_parts(ptr, 2) }; + assert_eq!(slice, [3, 4]); + } } diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index dc2ac0c9a3..c2c85a214b 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -223,6 +223,14 @@ macro_rules! as_usize_saturated { }; } +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(as_u64_saturated!($v)).unwrap_or(isize::MAX) + }; +} + macro_rules! as_usize_or_fail { ($interp:expr, $v:expr) => { as_usize_or_fail_ret!($interp, $v, ()) diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index f6822a39fc..e23aafa5c1 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -7,8 +7,8 @@ use bitvec::{ vec::BitVec, }; use core::fmt::Debug; -use std::sync::Arc; use legacy::JumpMap; +use std::sync::Arc; /// State of the [`Bytecode`] analysis. #[derive(Clone, Debug, PartialEq, Eq, Hash)] diff --git a/crates/primitives/src/bytecode/legacy/jump_map.rs b/crates/primitives/src/bytecode/legacy/jump_map.rs index 98ea62f19d..052773cf4e 100644 --- a/crates/primitives/src/bytecode/legacy/jump_map.rs +++ b/crates/primitives/src/bytecode/legacy/jump_map.rs @@ -1,10 +1,10 @@ use crate::{hex, keccak256, Bytes, B256, KECCAK_EMPTY}; -use std::{sync::Arc, vec::Vec}; 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)] From a638385db24b05908ecf879d93a9fab2b554ebaa Mon Sep 17 00:00:00 2001 From: rakita Date: Fri, 23 Feb 2024 03:15:42 +0100 Subject: [PATCH 08/54] eof rjump with tests --- crates/interpreter/src/instructions.rs | 2 +- .../interpreter/src/instructions/control.rs | 137 ++++++++++++++---- crates/interpreter/src/instructions/macros.rs | 11 +- crates/interpreter/src/instructions/opcode.rs | 2 + crates/interpreter/src/interpreter.rs | 2 +- 5 files changed, 123 insertions(+), 31 deletions(-) diff --git a/crates/interpreter/src/instructions.rs b/crates/interpreter/src/instructions.rs index 9a588509d1..a0bfda68cb 100644 --- a/crates/interpreter/src/instructions.rs +++ b/crates/interpreter/src/instructions.rs @@ -2,7 +2,6 @@ #[macro_use] pub mod macros; - pub mod arithmetic; pub mod bitwise; pub mod contract; @@ -15,4 +14,5 @@ pub mod memory; pub mod opcode; pub mod stack; pub mod system; + pub use opcode::{Instruction, OpCode, OPCODE_JUMPMAP}; diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index b414bead45..bf2200c011 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -1,53 +1,54 @@ -use revm_primitives::Bytes; - use crate::{ gas, - primitives::{Spec, U256}, + primitives::{Bytes, Spec, U256}, Host, InstructionResult, Interpreter, InterpreterResult, }; +fn read_i16(ptr: *const u8) -> i16 { + unsafe { i16::from_be_bytes(core::slice::from_raw_parts(ptr, 2).try_into().unwrap()) } +} + pub fn rjump(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); gas!(interpreter, gas::BASE); - let offset = unsafe { *interpreter.instruction_pointer.cast::() } as isize; - + let offset = 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 { *interpreter.instruction_pointer.cast::() } as isize; + offset += 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 = interpreter.instruction_pointer.cast::() as isize; - - // In spec it is (max_index+1)*2 but pointer is already incremented in - // `Interpreter::step` so for revm it is max_index*2 for destinations and +1 for max_index. - let mut offset = max_index * 2 + 1; + 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 { + offset += read_i16(unsafe { interpreter .instruction_pointer // offset for max_index that is one byte - .offset(1) - .cast::() - .offset(case) - } as isize; + .offset(1 + case * 2) + }) as isize; } interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset) }; @@ -89,11 +90,17 @@ pub fn jumpdest_or_nop(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::JUMPDEST); } -pub fn callf(interpreter: &mut Interpreter, _host: &mut H) {} +pub fn callf(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); +} -pub fn retf(interpreter: &mut Interpreter, _host: &mut H) {} +pub fn retf(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); +} -pub fn jumpf(interpreter: &mut Interpreter, _host: &mut H) {} +pub fn jumpf(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); +} pub fn pc(interpreter: &mut Interpreter, _host: &mut H) { panic_on_eof!(interpreter); @@ -153,20 +160,94 @@ pub fn unknown(interpreter: &mut Interpreter, _host: &mut H) { #[cfg(test)] mod test { + use revm_primitives::PragueSpec; + use super::*; - use crate::{opcode::RJUMP, Interpreter}; + use crate::{ + opcode::{make_instruction_table, NOP, RJUMP, RJUMPI, RJUMPV, STOP}, + DummyHost, Gas, Interpreter, + }; + + #[test] + fn rjump() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut interp = Interpreter::new_bytecode(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 sanity_rjump() { - let interp = Interpreter::new_bytecode(Bytes::from([RJUMP, 0x00, 0x00])); + fn rjumpi() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut interp = Interpreter::new_bytecode(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 ptr() { - let mut a = [1, 2, 3, 4, 5]; - let ptr = a.as_ptr(); - let ptr = ptr.cast::(); - let slice = unsafe { core::slice::from_raw_parts(ptr, 2) }; - assert_eq!(slice, [3, 4]); + fn rjumpv() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut interp = Interpreter::new_bytecode(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); } } diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index c2c85a214b..4d3b46e8cc 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -7,7 +7,7 @@ macro_rules! error_on_static_call { }; } -macro_rules! panic_on_eof { +macro_rules! error_on_disabled_eof { ($interp:expr) => { if $interp.is_static { $interp.instruction_result = InstructionResult::OpcodeDisabledInEof; @@ -16,6 +16,15 @@ macro_rules! panic_on_eof { }; } +macro_rules! panic_on_eof { + ($interp:expr) => { + if $interp.is_eof { + $interp.instruction_result = InstructionResult::OpcodeDisabledInEof; + return; + } + }; +} + macro_rules! check { ($interp:expr, $min:ident) => { // TODO: Force const-eval on the condition with a `const {}` block once they are stable diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index ddbbe85262..1d6689d999 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -86,6 +86,8 @@ where core::array::from_fn(|i| outer(table[i])) } +pub const NOP: u8 = JUMPDEST; + // 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 diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 726a1af549..dd1db08648 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -311,7 +311,7 @@ impl Interpreter { /// /// Internally it will increment instruction pointer by one. #[inline(always)] - fn step(&mut self, instruction_table: &[FN; 256], host: &mut H) + pub(crate) fn step(&mut self, instruction_table: &[FN; 256], host: &mut H) where FN: Fn(&mut Interpreter, &mut H), { From ad45264aff4737900c0c51538775caab2d01f39f Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 25 Feb 2024 03:01:58 +0100 Subject: [PATCH 09/54] EOF bytecode --- bins/revm-test/src/bin/analysis.rs | 16 +- crates/interpreter/src/function_stack.rs | 20 +++ crates/interpreter/src/instruction_result.rs | 8 +- .../interpreter/src/instructions/control.rs | 15 +- crates/interpreter/src/instructions/host.rs | 2 +- crates/interpreter/src/instructions/macros.rs | 4 +- crates/interpreter/src/instructions/stack.rs | 106 +++++++++++- crates/interpreter/src/instructions/system.rs | 2 +- crates/interpreter/src/interpreter.rs | 40 +++-- .../interpreter/src/interpreter/analysis.rs | 152 ++---------------- .../interpreter/src/interpreter/contract.rs | 19 ++- crates/interpreter/src/interpreter/stack.rs | 28 +++- crates/interpreter/src/lib.rs | 4 +- crates/primitives/src/bytecode.rs | 144 ++++++++--------- crates/primitives/src/bytecode/eof.rs | 11 ++ crates/primitives/src/bytecode/eof/body.rs | 8 +- crates/primitives/src/bytecode/eof/header.rs | 3 +- .../src/bytecode/eof/types_section.rs | 3 +- crates/primitives/src/bytecode/legacy.rs | 53 +++++- .../src/bytecode/legacy/jump_map.rs | 8 +- crates/primitives/src/db.rs | 6 + crates/primitives/src/env.rs | 2 - crates/primitives/src/state.rs | 2 +- crates/revm/benches/bench.rs | 21 ++- crates/revm/src/context.rs | 16 +- crates/revm/src/db/emptydb.rs | 2 +- crates/revm/src/db/in_memory_db.rs | 4 +- crates/revm/src/journaled_state.rs | 2 +- .../src/crates/primitives/bytecode.md | 6 +- 29 files changed, 390 insertions(+), 317 deletions(-) create mode 100644 crates/interpreter/src/function_stack.rs diff --git a/bins/revm-test/src/bin/analysis.rs b/bins/revm-test/src/bin/analysis.rs index 49fdbc57a7..3ba09869d6 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/crates/interpreter/src/function_stack.rs b/crates/interpreter/src/function_stack.rs new file mode 100644 index 0000000000..64e618d29d --- /dev/null +++ b/crates/interpreter/src/function_stack.rs @@ -0,0 +1,20 @@ +pub struct FunctionFrame { + /// 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, +} + +pub struct FunctionStack { + stack: Vec<()>, + current_idx: usize, +} + +impl FunctionStack { + pub fn new() -> Self { + Self { + stack: Vec::new(), + current_idx: 0, + } + } +} diff --git a/crates/interpreter/src/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index 9a5ef22cbe..8b38b2f9a5 100644 --- a/crates/interpreter/src/instruction_result.rs +++ b/crates/interpreter/src/instruction_result.rs @@ -47,8 +47,11 @@ pub enum InstructionResult { /* External error */ /// Fatal external error. Returned by database. FatalExternalError, - /* EOF */ + /// Opcode called that are not found in EOF. + /// This should not happen if the bytecode is validated correctly. OpcodeDisabledInEof, + /// Legacy contract is calling opcode that is enabled only in EOF. + EOFOpcodeDisabledInLegacy, } impl From for InstructionResult { @@ -138,6 +141,7 @@ macro_rules! return_error { | InstructionResult::CreateInitCodeSizeLimit | InstructionResult::FatalExternalError | InstructionResult::OpcodeDisabledInEof + | InstructionResult::EOFOpcodeDisabledInLegacy }; } @@ -260,6 +264,8 @@ impl From for SuccessOrHalt { InstructionResult::FatalExternalError => Self::FatalExternalError, // TODO(EOF) Check how to propagate error that should be a EVM panic! InstructionResult::OpcodeDisabledInEof => Self::FatalExternalError, + // TODO(EOF) make proper error + InstructionResult::EOFOpcodeDisabledInLegacy => Self::FatalExternalError, } } } diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index bf2200c011..46400cfab6 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -62,8 +62,7 @@ pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { if interpreter.contract.is_valid_jump(dest) { // SAFETY: In analysis we are checking create our jump table and we do check above to be // sure that jump is safe to execute. - interpreter.instruction_pointer = - unsafe { interpreter.contract.bytecode.as_ptr().add(dest) }; + interpreter.instruction_pointer = unsafe { interpreter.bytecode.as_ptr().add(dest) }; } else { interpreter.instruction_result = InstructionResult::InvalidJump; } @@ -78,8 +77,7 @@ pub fn jumpi(interpreter: &mut Interpreter, _host: &mut H) { if interpreter.contract.is_valid_jump(dest) { // SAFETY: In analysis we are checking if jump is valid destination and // this `if` makes this unsafe block safe. - interpreter.instruction_pointer = - unsafe { interpreter.contract.bytecode.as_ptr().add(dest) }; + interpreter.instruction_pointer = unsafe { interpreter.bytecode.as_ptr().add(dest) }; } else { interpreter.instruction_result = InstructionResult::InvalidJump } @@ -92,6 +90,15 @@ pub fn jumpdest_or_nop(interpreter: &mut Interpreter, _host: &mut H) { pub fn callf(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); + gas!(interpreter, gas::LOW); + + let idx = read_i16(interpreter.instruction_pointer) as isize; + // TODO Check stack with EOF types. + if interpreter.callf_stack.len() < 1024 { + // TODO(EOF) change error + interpreter.instruction_result = InstructionResult::CallStackOverflow; + return; + } } pub fn retf(interpreter: &mut Interpreter, _host: &mut H) { diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index d381a2a425..9b69e87477 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -116,7 +116,7 @@ pub fn extcodecopy(interpreter: &mut Interpreter, host: &mu // 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) { diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index 4d3b46e8cc..b3997d7deb 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -9,8 +9,8 @@ macro_rules! error_on_static_call { macro_rules! error_on_disabled_eof { ($interp:expr) => { - if $interp.is_static { - $interp.instruction_result = InstructionResult::OpcodeDisabledInEof; + if !$interp.is_eof { + $interp.instruction_result = InstructionResult::EOFOpcodeDisabledInLegacy; return; } }; diff --git a/crates/interpreter/src/instructions/stack.rs b/crates/interpreter/src/instructions/stack.rs index 3c35c24296..608c9f3444 100644 --- a/crates/interpreter/src/instructions/stack.rs +++ b/crates/interpreter/src/instructions/stack.rs @@ -39,20 +39,116 @@ pub fn push(interpreter: &mut Interpreter, _host: &mut 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) {} +pub fn dupn(interpreter: &mut Interpreter, _host: &mut H) { + 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) { + 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) { + 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; + } -pub fn swapn(interpreter: &mut Interpreter, _host: &mut H) {} + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; +} + +#[cfg(test)] +mod test { + use revm_primitives::PragueSpec; + + use super::*; + use crate::{ + opcode::{make_instruction_table, DUPN, EXCHANGE, SWAPN}, + primitives::Bytes, + DummyHost, Gas, Interpreter, + }; + + #[test] + fn dupn() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut interp = + Interpreter::new_bytecode(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(Bytes::from([SWAPN, 0x00, SWAPN, 0x01])); + interp.is_eof = true; + interp.gas = Gas::new(10000); -pub fn exchange(interpreter: &mut Interpreter, _host: &mut H) {} + 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(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 10339d8b72..4aeb9af7ea 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -52,7 +52,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(), ); } diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index dd1db08648..ce096f3729 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -3,7 +3,6 @@ mod contract; mod shared_memory; mod stack; -pub use analysis::BytecodeLocked; pub use contract::Contract; pub use shared_memory::{next_multiple_of_32, SharedMemory}; pub use stack::{Stack, STACK_LIMIT}; @@ -21,15 +20,21 @@ pub use self::shared_memory::EMPTY_SHARED_MEMORY; #[derive(Debug)] pub struct Interpreter { - /// Contract information and invoking data - pub contract: Box, /// The current instruction pointer. pub instruction_pointer: *const u8, + /// The gas state. + pub gas: Gas, + /// Contract information and invoking data + pub contract: Box, /// 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, /// Shared memory. /// /// Note: This field is only set while running the interpreter loop. @@ -37,6 +42,8 @@ pub struct Interpreter { pub shared_memory: SharedMemory, /// Stack. pub stack: Stack, + /// CALLF, RETF stack. + pub callf_stack: Vec<(usize, usize)>, /// The return data buffer for internal calls. /// It has multi usage: /// @@ -45,8 +52,6 @@ pub struct Interpreter { pub return_data_buffer: Bytes, /// Whether the interpreter is in "staticcall" mode, meaning no state changes can happen. pub is_static: bool, - /// Whether we are Interpreting the Ethereum Object Format (EOF) bytecode. - pub is_eof: bool, /// Actions that the EVM should do. /// /// Set inside CALL or CREATE instructions and RETURN or REVERT instructions. Additionally those instructions will set @@ -56,7 +61,7 @@ pub struct Interpreter { impl Default for Interpreter { fn default() -> Self { - Self::new(Box::new(Contract::default()), 0, false, false) + Self::new(Box::new(Contract::default()), 0, false) } } @@ -124,12 +129,19 @@ impl InterpreterAction { impl Interpreter { /// Create new interpreter - pub fn new(contract: Box, gas_limit: u64, is_static: bool, is_eof: bool) -> Self { + pub fn new(contract: Box, 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, + callf_stack: vec![(0, 0)], is_static, is_eof, return_data_buffer: Bytes::new(), @@ -146,14 +158,13 @@ impl Interpreter { Box::new(Contract::new( Bytes::new(), crate::primitives::Bytecode::new_raw(bytecode), - crate::primitives::B256::default(), + None, crate::primitives::Address::default(), crate::primitives::Address::default(), U256::ZERO, )), 0, false, - false, ) } @@ -301,10 +312,7 @@ 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. diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 25079c642a..aacdf9bde3 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -1,11 +1,11 @@ +use revm_primitives::LegacyAnalyzedBytecode; + use crate::opcode; use crate::primitives::{ bitvec::prelude::{bitvec, BitVec, Lsb0}, - keccak256, - legacy::JumpMap, - Bytecode, BytecodeState, Bytes, B256, KECCAK_EMPTY, + legacy::JumpTable, + Bytecode, }; -use core::fmt; use std::sync::Arc; /// Perform bytecode analysis. @@ -14,25 +14,21 @@ use std::sync::Arc; /// /// If the bytecode is already analyzed, it is returned as-is. 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(); + (bytecode, len) } - BytecodeState::Checked { len } => (bytecode.bytecode, len), - _ => return bytecode, + Bytecode::LegacyAnalyzed(analyzed) => return Bytecode::LegacyAnalyzed(analyzed), + _ => unreachable!("TODO(eof) Support for EOF"), }; - 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(); @@ -57,125 +53,5 @@ fn analyze(code: &[u8]) -> JumpMap { } } - JumpMap(Arc::new(jumps)) -} - -/// An analyzed bytecode. -#[derive(Clone)] -pub struct BytecodeLocked { - bytecode: Bytes, - original_len: usize, - jump_map: JumpMap, -} - -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() - } -} - -impl Default for BytecodeLocked { - #[inline] - fn default() -> Self { - Bytecode::default() - .try_into() - .expect("Bytecode default is analysed code") - } -} - -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(()) - } - } -} - -impl BytecodeLocked { - /// Returns a raw pointer to the underlying byte slice. - #[inline] - pub fn as_ptr(&self) -> *const u8 { - self.bytecode.as_ptr() - } - - /// Returns the length of the bytecode. - #[inline] - pub fn len(&self) -> usize { - self.original_len - } - - /// Returns whether the bytecode is empty. - #[inline] - pub fn is_empty(&self) -> bool { - self.original_len == 0 - } - - /// Calculate hash of the bytecode. - #[inline] - pub fn hash_slow(&self) -> B256 { - if self.is_empty() { - KECCAK_EMPTY - } else { - keccak256(self.original_bytecode_slice()) - } - } - - #[inline] - pub fn unlock(self) -> Bytecode { - Bytecode { - bytecode: self.bytecode, - state: BytecodeState::Analysed { - len: self.original_len, - jump_map: self.jump_map, - }, - } - } - - /// 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 - } - - /// 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) - } - - /// 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() - ), - } - } - - /// Returns a reference to the jump map. - #[inline] - pub fn jump_map(&self) -> &JumpMap { - &self.jump_map - } + JumpTable(Arc::new(jumps)) } diff --git a/crates/interpreter/src/interpreter/contract.rs b/crates/interpreter/src/interpreter/contract.rs index a5896cc865..6a88507a5f 100644 --- a/crates/interpreter/src/interpreter/contract.rs +++ b/crates/interpreter/src/interpreter/contract.rs @@ -1,4 +1,4 @@ -use super::analysis::{to_analysed, BytecodeLocked}; +use super::analysis::to_analysed; use crate::primitives::{Address, Bytecode, Bytes, Env, TransactTo, B256, U256}; use crate::CallContext; @@ -9,9 +9,9 @@ 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, + pub bytecode: Bytecode, + /// Bytecode hash for legacy. For EOF this would be None. + pub hash: Option, /// Contract address pub address: Address, /// Caller of the EVM. @@ -26,7 +26,7 @@ impl Contract { pub fn new( input: Bytes, bytecode: Bytecode, - hash: B256, + hash: Option, address: Address, caller: Address, value: U256, @@ -45,7 +45,7 @@ impl Contract { /// 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, @@ -65,7 +65,7 @@ impl Contract { pub fn new_with_context( input: Bytes, bytecode: Bytecode, - hash: B256, + hash: Option, call_context: &CallContext, ) -> Self { Self::new( @@ -81,6 +81,9 @@ impl Contract { /// 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/stack.rs b/crates/interpreter/src/interpreter/stack.rs index 9692695cf2..59016ef9eb 100644 --- a/crates/interpreter/src/interpreter/stack.rs +++ b/crates/interpreter/src/interpreter/stack.rs @@ -201,9 +201,9 @@ 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) @@ -211,7 +211,7 @@ impl Stack { // 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); + core::ptr::copy_nonoverlapping(data.add(len - n), data.add(len), 1); self.data.set_len(len + 1); } Ok(()) @@ -220,13 +220,27 @@ impl Stack { /// 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 len <= N { + if n >= 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, 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(); + 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); Ok(()) } diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index 861853dcd1..9f848196ef 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -30,8 +30,8 @@ pub use inner_models::*; 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, InterpreterAction, InterpreterResult, + SharedMemory, Stack, EMPTY_SHARED_MEMORY, STACK_LIMIT, }; pub use primitives::{MAX_CODE_SIZE, MAX_INITCODE_SIZE}; diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index e23aafa5c1..fd19d059cb 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -1,60 +1,44 @@ pub mod eof; pub mod legacy; -use crate::{hex, keccak256, Bytes, B256, KECCAK_EMPTY}; -use bitvec::{ - prelude::{bitvec, Lsb0}, - vec::BitVec, -}; -use core::fmt::Debug; -use legacy::JumpMap; -use std::sync::Arc; +pub use eof::Eof; +pub use legacy::{JumpTable, LegacyAnalyzedBytecode}; + +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, } } @@ -67,13 +51,15 @@ impl Bytecode { } } + /// 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 @@ -81,37 +67,59 @@ impl 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 - pub unsafe fn new_checked(bytecode: Bytes, len: usize) -> Self { - Self { + /// that it is safe to iteßrate over bytecode without checking lengths + 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.original_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 { + match self { + Self::LegacyRaw(_) => false, + _ => true, + } } /// 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().expect("TODO see if we should remove Option"), } } - /// 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.len(), } } @@ -120,26 +128,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 index 519ef2ee33..475cafe09c 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -8,6 +8,8 @@ pub use body::EofBody; pub use header::EofHeader; pub use types_section::TypesSection; +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Eof { pub header: EofHeader, pub body: EofBody, @@ -15,6 +17,15 @@ pub struct Eof { } impl Eof { + /// Returns len of the header and body in bytes. + pub fn len(&self) -> usize { + self.header.len() + self.header.body_len() + } + + pub fn raw(&self) -> Option { + self.raw.clone() + } + pub fn decode(raw: Bytes) -> Result { let (header, _) = EofHeader::decode(&raw)?; let body = EofBody::decode(&raw, &header)?; diff --git a/crates/primitives/src/bytecode/eof/body.rs b/crates/primitives/src/bytecode/eof/body.rs index e08e5f26d6..75fb91ea16 100644 --- a/crates/primitives/src/bytecode/eof/body.rs +++ b/crates/primitives/src/bytecode/eof/body.rs @@ -2,7 +2,8 @@ use crate::Bytes; use super::{EofHeader, TypesSection}; -#[derive(Default, Clone, Debug)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct EofBody { types_section: Vec, code_section: Vec, @@ -12,6 +13,11 @@ pub struct EofBody { } impl EofBody { + // Get code section + pub fn code(&self, index: usize) -> Option<&Bytes> { + self.code_section.get(index) + } + pub fn decode(input: &Bytes, header: &EofHeader) -> Result { let header_len = header.len(); let partial_body_len = header.sum_code_sizes + header.sum_container_sizes; diff --git a/crates/primitives/src/bytecode/eof/header.rs b/crates/primitives/src/bytecode/eof/header.rs index 6749fb34d7..b66ccc3d49 100644 --- a/crates/primitives/src/bytecode/eof/header.rs +++ b/crates/primitives/src/bytecode/eof/header.rs @@ -1,7 +1,8 @@ use super::decode_helpers::{consume_u16, consume_u8}; /// EOF Header containing -#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[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. diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs index d1da18711c..a60d2b4856 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -1,6 +1,7 @@ use super::decode_helpers::{consume_u16, consume_u8}; -#[derive(Debug, Clone, Default, PartialEq, Eq, Copy)] +#[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, diff --git a/crates/primitives/src/bytecode/legacy.rs b/crates/primitives/src/bytecode/legacy.rs index 189a00267e..47fbd23849 100644 --- a/crates/primitives/src/bytecode/legacy.rs +++ b/crates/primitives/src/bytecode/legacy.rs @@ -1,3 +1,54 @@ mod jump_map; -pub use jump_map::JumpMap; +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: Bytes, + original_len: usize, + 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, + } + } + + pub fn bytes(&self) -> Bytes { + self.bytecode.clone() + } + + pub fn original_len(&self) -> usize { + self.original_len + } + + pub fn original_bytes(&self) -> Bytes { + self.bytecode.slice(0..self.original_len) + } + + 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 index 052773cf4e..bda26738df 100644 --- a/crates/primitives/src/bytecode/legacy/jump_map.rs +++ b/crates/primitives/src/bytecode/legacy/jump_map.rs @@ -9,17 +9,17 @@ 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 struct JumpTable(pub Arc>); -impl Debug for JumpMap { +impl Debug for JumpTable { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("JumpMap") + f.debug_struct("JumpTable") .field("map", &hex::encode(self.0.as_raw_slice())) .finish() } } -impl JumpMap { +impl JumpTable { /// Get the raw bytes of the jump map #[inline] pub fn as_slice(&self) -> &[u8] { diff --git a/crates/primitives/src/db.rs b/crates/primitives/src/db.rs index 0456b03432..02666cb2cb 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 aa2f3f4cc2..3bb237ae8b 100644 --- a/crates/primitives/src/env.rs +++ b/crates/primitives/src/env.rs @@ -699,8 +699,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/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 e7bc5f3681..f55c2667dc 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(); @@ -114,8 +112,7 @@ fn bench_eval(g: &mut BenchmarkGroup<'_, WallTime>, evm: &mut Evm<'static, (), B // replace memory with empty memory to use it inside interpreter. // Later return memory back. let temp = core::mem::replace(&mut shared_memory, EMPTY_SHARED_MEMORY); - let mut interpreter = - Interpreter::new(Box::new(contract.clone()), u64::MAX, false, false); + let mut interpreter = Interpreter::new(Box::new(contract.clone()), u64::MAX, false); let res = interpreter.run(temp, &instruction_table, &mut host); shared_memory = interpreter.take_memory(); host.clear(); diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index 4da7d4b006..8b3fbf965e 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -305,12 +305,13 @@ impl EvmContext { } // Create address - let mut init_code_hash = B256::ZERO; + let mut init_code_hash = None; let created_address = match inputs.scheme { CreateScheme::Create => inputs.caller.create(old_nonce), CreateScheme::Create2 { salt } => { - init_code_hash = keccak256(&inputs.init_code); - inputs.caller.create2(salt.to_be_bytes(), init_code_hash) + let hash = keccak256(&inputs.init_code); + init_code_hash = Some(hash); + inputs.caller.create2(salt.to_be_bytes(), hash) } }; @@ -347,7 +348,7 @@ impl EvmContext { Ok(FrameOrResult::new_create_frame( created_address, checkpoint, - Interpreter::new(contract, gas.limit(), false, false), + Interpreter::new(contract, gas.limit(), false), )) } @@ -416,7 +417,7 @@ impl EvmContext { let contract = Box::new(Contract::new_with_context( inputs.input.clone(), bytecode, - code_hash, + Some(code_hash), &inputs.context, )); // TODO(eof) flag @@ -424,7 +425,7 @@ impl EvmContext { Ok(FrameOrResult::new_call_frame( inputs.return_memory_offset.clone(), checkpoint, - Interpreter::new(contract, gas.limit(), inputs.is_static, false), + Interpreter::new(contract, gas.limit(), inputs.is_static), )) } else { self.journaled_state.checkpoint_commit(); @@ -547,9 +548,6 @@ impl EvmContext { // 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 bca142e3ae..ecfff66e7e 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/journaled_state.rs b/crates/revm/src/journaled_state.rs index 65f93389a5..f0c2c9c8fb 100644 --- a/crates/revm/src/journaled_state.rs +++ b/crates/revm/src/journaled_state.rs @@ -591,7 +591,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 2c29f1beb6f99b1840eb9c4b3aa6d73cf1c55d02 Mon Sep 17 00:00:00 2001 From: rakita Date: Mon, 26 Feb 2024 15:30:38 +0100 Subject: [PATCH 10/54] callf, retf, jumpf --- crates/interpreter/src/function_stack.rs | 41 ++++++++++++++-- crates/interpreter/src/gas/constants.rs | 1 + crates/interpreter/src/instruction_result.rs | 10 ++++ crates/interpreter/src/instructions.rs | 1 + .../interpreter/src/instructions/control.rs | 48 +++++++++++++++---- .../interpreter/src/instructions/utility.rs | 7 +++ crates/interpreter/src/interpreter.rs | 23 +++++++-- crates/interpreter/src/lib.rs | 2 + 8 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 crates/interpreter/src/instructions/utility.rs diff --git a/crates/interpreter/src/function_stack.rs b/crates/interpreter/src/function_stack.rs index 64e618d29d..5923bde6ec 100644 --- a/crates/interpreter/src/function_stack.rs +++ b/crates/interpreter/src/function_stack.rs @@ -1,20 +1,51 @@ -pub struct FunctionFrame { +/// Function return frame. +/// Needed information for returning from a function. +#[derive(Debug, Default)] +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, } +#[derive(Debug, Default)] pub struct FunctionStack { - stack: Vec<()>, - current_idx: usize, + pub return_stack: Vec, + pub current_code_idx: usize, } impl FunctionStack { pub fn new() -> Self { Self { - stack: Vec::new(), - current_idx: 0, + 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/constants.rs b/crates/interpreter/src/gas/constants.rs index 2354b715ff..3f81640be5 100644 --- a/crates/interpreter/src/gas/constants.rs +++ b/crates/interpreter/src/gas/constants.rs @@ -2,6 +2,7 @@ pub const ZERO: u64 = 0; pub const BASE: u64 = 2; pub const VERYLOW: u64 = 3; pub const CONDITION_JUMP_GAS: u64 = 4; +pub const RETF_GAS: u64 = 4; pub const LOW: u64 = 5; pub const MID: u64 = 8; pub const HIGH: u64 = 10; diff --git a/crates/interpreter/src/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index 8b38b2f9a5..f6c8bef6fe 100644 --- a/crates/interpreter/src/instruction_result.rs +++ b/crates/interpreter/src/instruction_result.rs @@ -52,6 +52,10 @@ pub enum InstructionResult { OpcodeDisabledInEof, /// Legacy contract is calling opcode that is enabled only in EOF. EOFOpcodeDisabledInLegacy, + /// EOF function stack overflow + EOFFunctionStackOverflow, + /// EOF idx is out of bounds + EOFCodeIdxOutOfBounds, } impl From for InstructionResult { @@ -142,6 +146,8 @@ macro_rules! return_error { | InstructionResult::FatalExternalError | InstructionResult::OpcodeDisabledInEof | InstructionResult::EOFOpcodeDisabledInLegacy + | InstructionResult::EOFFunctionStackOverflow + | InstructionResult::EOFCodeIdxOutOfBounds }; } @@ -266,6 +272,10 @@ impl From for SuccessOrHalt { InstructionResult::OpcodeDisabledInEof => Self::FatalExternalError, // TODO(EOF) make proper error InstructionResult::EOFOpcodeDisabledInLegacy => Self::FatalExternalError, + // TODO(EOF) + InstructionResult::EOFFunctionStackOverflow => Self::FatalExternalError, + // TODO(EOF) + InstructionResult::EOFCodeIdxOutOfBounds => Self::FatalExternalError, } } } diff --git a/crates/interpreter/src/instructions.rs b/crates/interpreter/src/instructions.rs index a0bfda68cb..634ec284cc 100644 --- a/crates/interpreter/src/instructions.rs +++ b/crates/interpreter/src/instructions.rs @@ -14,5 +14,6 @@ pub mod memory; pub mod opcode; pub mod stack; pub mod system; +pub mod utility; pub use opcode::{Instruction, OpCode, OPCODE_JUMPMAP}; diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index 46400cfab6..28de13a9bb 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -1,13 +1,10 @@ +use super::utility::{read_i16, read_u16}; use crate::{ gas, primitives::{Bytes, Spec, U256}, Host, InstructionResult, Interpreter, InterpreterResult, }; -fn read_i16(ptr: *const u8) -> i16 { - unsafe { i16::from_be_bytes(core::slice::from_raw_parts(ptr, 2).try_into().unwrap()) } -} - pub fn rjump(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::BASE); @@ -92,21 +89,44 @@ pub fn callf(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::LOW); - let idx = read_i16(interpreter.instruction_pointer) as isize; + let idx = read_u16(interpreter.instruction_pointer) as usize; // TODO Check stack with EOF types. - if interpreter.callf_stack.len() < 1024 { - // TODO(EOF) change error - interpreter.instruction_result = InstructionResult::CallStackOverflow; + + 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 = 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) { @@ -257,4 +277,16 @@ mod test { interp.step(&table, &mut host); assert_eq!(interp.program_counter(), 8); } + + #[test] + fn callf() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut interp = Interpreter::new_bytecode(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); + } } diff --git a/crates/interpreter/src/instructions/utility.rs b/crates/interpreter/src/instructions/utility.rs new file mode 100644 index 0000000000..eb7909e9a6 --- /dev/null +++ b/crates/interpreter/src/instructions/utility.rs @@ -0,0 +1,7 @@ +pub(crate) fn read_i16(ptr: *const u8) -> i16 { + unsafe { i16::from_be_bytes(core::slice::from_raw_parts(ptr, 2).try_into().unwrap()) } +} + +pub(crate) fn read_u16(ptr: *const u8) -> u16 { + unsafe { 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 ce096f3729..3687985698 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -9,10 +9,10 @@ pub use stack::{Stack, STACK_LIMIT}; use crate::{ primitives::Bytes, push, push_b256, return_ok, return_revert, CallInputs, CallOutcome, - CreateInputs, CreateOutcome, Gas, Host, InstructionResult, + CreateInputs, CreateOutcome, FunctionStack, Gas, Host, InstructionResult, }; use core::cmp::min; -use revm_primitives::U256; +use revm_primitives::{Bytecode, U256}; use std::borrow::ToOwned; use std::boxed::Box; @@ -42,8 +42,8 @@ pub struct Interpreter { pub shared_memory: SharedMemory, /// Stack. pub stack: Stack, - /// CALLF, RETF stack. - pub callf_stack: Vec<(usize, usize)>, + /// EOF function stack. + pub function_stack: FunctionStack, /// The return data buffer for internal calls. /// It has multi usage: /// @@ -141,7 +141,7 @@ impl Interpreter { contract, gas: Gas::new(gas_limit), instruction_result: InstructionResult::Continue, - callf_stack: vec![(0, 0)], + function_stack: FunctionStack::default(), is_static, is_eof, return_data_buffer: Bytes::new(), @@ -168,6 +168,19 @@ impl Interpreter { ) } + /// 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().offset(pc as isize) }; + } + /// 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 diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index 9f848196ef..b0625d6356 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -14,6 +14,7 @@ mod macros; mod call_outcome; mod create_outcome; +mod function_stack; pub mod gas; mod host; mod inner_models; @@ -24,6 +25,7 @@ mod interpreter; // 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::*; From ecc44671cfa1cb8a9bf5cd4b83943fac965ec173 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 27 Feb 2024 19:23:26 +0100 Subject: [PATCH 11/54] tests for callf,retf,jumpf --- crates/interpreter/src/function_stack.rs | 8 ++- .../interpreter/src/instructions/control.rs | 67 +++++++++++++++---- crates/interpreter/src/instructions/stack.rs | 14 ++-- crates/interpreter/src/interpreter.rs | 4 +- .../interpreter/src/interpreter/analysis.rs | 4 +- crates/primitives/src/bytecode/eof.rs | 12 ++++ crates/primitives/src/bytecode/eof/body.rs | 18 ++--- .../src/bytecode/eof/types_section.rs | 2 +- 8 files changed, 98 insertions(+), 31 deletions(-) diff --git a/crates/interpreter/src/function_stack.rs b/crates/interpreter/src/function_stack.rs index 5923bde6ec..e9cfe3f846 100644 --- a/crates/interpreter/src/function_stack.rs +++ b/crates/interpreter/src/function_stack.rs @@ -1,6 +1,6 @@ /// Function return frame. /// Needed information for returning from a function. -#[derive(Debug, Default)] +#[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, @@ -8,6 +8,12 @@ pub struct FunctionReturnFrame { pub pc: usize, } +impl FunctionReturnFrame { + pub fn new(idx: usize, pc: usize) -> Self { + Self { idx, pc } + } +} + #[derive(Debug, Default)] pub struct FunctionStack { pub return_stack: Vec, diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index 28de13a9bb..da025a9eb6 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -187,19 +187,21 @@ pub fn unknown(interpreter: &mut Interpreter, _host: &mut H) { #[cfg(test)] mod test { - use revm_primitives::PragueSpec; + use revm_primitives::{bytes, eof::EofBody, Bytecode, Eof, PragueSpec}; use super::*; use crate::{ - opcode::{make_instruction_table, NOP, RJUMP, RJUMPI, RJUMPV, STOP}, - DummyHost, Gas, Interpreter, + 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(Bytes::from([RJUMP, 0x00, 0x02, STOP, STOP])); + let mut interp = Interpreter::new_bytecode(Bytecode::LegacyRaw(Bytes::from([ + RJUMP, 0x00, 0x02, STOP, STOP, + ]))); interp.is_eof = true; interp.gas = Gas::new(10000); @@ -211,9 +213,9 @@ mod test { fn rjumpi() { let table = make_instruction_table::<_, PragueSpec>(); let mut host = DummyHost::default(); - let mut interp = Interpreter::new_bytecode(Bytes::from([ + 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(); @@ -231,7 +233,7 @@ mod test { fn rjumpv() { let table = make_instruction_table::<_, PragueSpec>(); let mut host = DummyHost::default(); - let mut interp = Interpreter::new_bytecode(Bytes::from([ + let mut interp = Interpreter::new_bytecode(Bytecode::LegacyRaw(Bytes::from([ RJUMPV, 0x01, // max index, 0 and 1 0x00, // first x0001 @@ -245,7 +247,7 @@ mod test { 0xFF, (-12i8) as u8, STOP, - ])); + ]))); interp.is_eof = true; interp.gas = Gas::new(1000); @@ -278,15 +280,56 @@ mod test { assert_eq!(interp.program_counter(), 8); } + fn dummy_eof() -> Eof { + let bytes = bytes!("ef000101000402000100010400000000800000fe"); + Eof::decode(bytes).unwrap() + } + #[test] - fn callf() { + fn callf_retf() { let table = make_instruction_table::<_, PragueSpec>(); let mut host = DummyHost::default(); - let mut interp = Interpreter::new_bytecode(Bytes::from([RJUMP, 0x00, 0x02, STOP, STOP])); - interp.is_eof = true; + 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.program_counter(), 5); + + 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/stack.rs b/crates/interpreter/src/instructions/stack.rs index 608c9f3444..bb21ddf2fe 100644 --- a/crates/interpreter/src/instructions/stack.rs +++ b/crates/interpreter/src/instructions/stack.rs @@ -83,7 +83,7 @@ pub fn exchange(interpreter: &mut Interpreter, _host: &mut H) { #[cfg(test)] mod test { - use revm_primitives::PragueSpec; + use revm_primitives::{Bytecode, PragueSpec}; use super::*; use crate::{ @@ -96,8 +96,9 @@ mod test { fn dupn() { let table = make_instruction_table::<_, PragueSpec>(); let mut host = DummyHost::default(); - let mut interp = - Interpreter::new_bytecode(Bytes::from([DUPN, 0x00, DUPN, 0x01, DUPN, 0x02])); + 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); @@ -115,7 +116,8 @@ mod test { fn swapn() { let table = make_instruction_table::<_, PragueSpec>(); let mut host = DummyHost::default(); - let mut interp = Interpreter::new_bytecode(Bytes::from([SWAPN, 0x00, SWAPN, 0x01])); + let mut interp = + Interpreter::new_bytecode(Bytecode::LegacyRaw(Bytes::from([SWAPN, 0x00, SWAPN, 0x01]))); interp.is_eof = true; interp.gas = Gas::new(10000); @@ -134,7 +136,9 @@ mod test { fn exchange() { let table = make_instruction_table::<_, PragueSpec>(); let mut host = DummyHost::default(); - let mut interp = Interpreter::new_bytecode(Bytes::from([EXCHANGE, 0x00, EXCHANGE, 0x11])); + let mut interp = Interpreter::new_bytecode(Bytecode::LegacyRaw(Bytes::from([ + EXCHANGE, 0x00, EXCHANGE, 0x11, + ]))); interp.is_eof = true; interp.gas = Gas::new(10000); diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 3687985698..4943dbfbb1 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -153,11 +153,11 @@ impl Interpreter { /// Test related helper #[cfg(test)] - pub fn new_bytecode(bytecode: Bytes) -> Self { + pub fn new_bytecode(bytecode: Bytecode) -> Self { Self::new( Box::new(Contract::new( Bytes::new(), - crate::primitives::Bytecode::new_raw(bytecode), + bytecode, None, crate::primitives::Address::default(), crate::primitives::Address::default(), diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index aacdf9bde3..60305ffc53 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -13,14 +13,14 @@ use std::sync::Arc; /// 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 (bytes, len) = match bytecode { Bytecode::LegacyRaw(bytecode) => { let len = bytecode.len(); (bytecode, len) } - Bytecode::LegacyAnalyzed(analyzed) => return Bytecode::LegacyAnalyzed(analyzed), - _ => unreachable!("TODO(eof) Support for EOF"), + n => return n, }; let jump_table = analyze(bytes.as_ref()); diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index 475cafe09c..d2690ddeb7 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -43,3 +43,15 @@ impl Eof { // data section in the body. Other sections would still pin old raw Bytes. } } + +#[cfg(test)] +mod test { + + use super::*; + + #[test] + fn decode_eof() { + let bytes = alloy_primitives::bytes!("ef000101000402000100010400000000800000fe"); + Eof::decode(bytes).unwrap(); + } +} diff --git a/crates/primitives/src/bytecode/eof/body.rs b/crates/primitives/src/bytecode/eof/body.rs index 75fb91ea16..49aae02218 100644 --- a/crates/primitives/src/bytecode/eof/body.rs +++ b/crates/primitives/src/bytecode/eof/body.rs @@ -5,11 +5,11 @@ use super::{EofHeader, TypesSection}; #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct EofBody { - types_section: Vec, - code_section: Vec, - container_section: Vec, - data_section: Bytes, - is_data_filled: bool, + pub types_section: Vec, + pub code_section: Vec, + pub container_section: Vec, + pub data_section: Bytes, + pub is_data_filled: bool, } impl EofBody { @@ -20,7 +20,8 @@ impl EofBody { pub fn decode(input: &Bytes, header: &EofHeader) -> Result { let header_len = header.len(); - let partial_body_len = header.sum_code_sizes + header.sum_container_sizes; + 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 { @@ -43,13 +44,14 @@ impl EofBody { // 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..size)); + 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..size)); + body.container_section + .push(input.slice(start..start + size)); start += size; } diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs index a60d2b4856..22cff0915c 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -29,7 +29,7 @@ impl TypesSection { } pub fn validate(&self) -> Result<(), ()> { - if self.inputs <= 0x7f || self.outputs <= 0x80 || self.max_stack_size <= 0x03FF { + if self.inputs > 0x7f || self.outputs > 0x80 || self.max_stack_size > 0x03FF { return Err(()); } Ok(()) From 3979a12a263ff2b0653318915437313b0c7bc4e5 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 27 Feb 2024 21:08:57 +0100 Subject: [PATCH 12/54] small rename --- crates/interpreter/src/instructions/control.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index da025a9eb6..d5511ab19d 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -187,7 +187,7 @@ pub fn unknown(interpreter: &mut Interpreter, _host: &mut H) { #[cfg(test)] mod test { - use revm_primitives::{bytes, eof::EofBody, Bytecode, Eof, PragueSpec}; + use revm_primitives::{bytes, Bytecode, Eof, PragueSpec}; use super::*; use crate::{ @@ -286,7 +286,7 @@ mod test { } #[test] - fn callf_retf() { + fn callf_retf_jumpf() { let table = make_instruction_table::<_, PragueSpec>(); let mut host = DummyHost::default(); let mut eof = dummy_eof(); From a440503e53dcc9a4b22c206cf094f18b605b5c7a Mon Sep 17 00:00:00 2001 From: rakita Date: Wed, 28 Feb 2024 16:33:32 +0100 Subject: [PATCH 13/54] add dataload, dataloadn and datacopy opcodes --- crates/interpreter/src/gas/constants.rs | 5 + crates/interpreter/src/instructions/data.rs | 218 +++++++++++++++++- crates/interpreter/src/interpreter.rs | 7 +- .../src/interpreter/shared_memory.rs | 1 - crates/primitives/src/bytecode.rs | 8 + crates/primitives/src/bytecode/eof.rs | 34 ++- .../src/bytecode/legacy/jump_map.rs | 10 +- 7 files changed, 263 insertions(+), 20 deletions(-) diff --git a/crates/interpreter/src/gas/constants.rs b/crates/interpreter/src/gas/constants.rs index 3f81640be5..2ba845ac13 100644 --- a/crates/interpreter/src/gas/constants.rs +++ b/crates/interpreter/src/gas/constants.rs @@ -1,8 +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; diff --git a/crates/interpreter/src/instructions/data.rs b/crates/interpreter/src/instructions/data.rs index 6d8c18379d..0d00f882c8 100644 --- a/crates/interpreter/src/instructions/data.rs +++ b/crates/interpreter/src/instructions/data.rs @@ -1,16 +1,214 @@ use crate::{ - gas::{self, COLD_ACCOUNT_ACCESS_COST, WARM_STORAGE_READ_COST}, - interpreter::{Interpreter, InterpreterAction}, - primitives::{Address, Bytes, Log, LogData, Spec, SpecId::*, B256, U256}, - CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, Host, InstructionResult, - Transfer, MAX_INITCODE_SIZE, + gas::{BASE, DATA_LOAD_GAS, VERYLOW}, + instructions::utility::read_u16, + interpreter::Interpreter, + primitives::U256, + Host, InstructionResult, }; -use std::{boxed::Box, vec::Vec}; -pub fn data_load(interpreter: &mut Interpreter, host: &mut H) {} +pub fn data_load(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, DATA_LOAD_GAS); + pop_top!(interpreter, offset); -pub fn data_loadn(interpreter: &mut Interpreter, host: &mut H) {} + let offset_usize = as_usize_saturated!(offset); -pub fn data_size(interpreter: &mut Interpreter, host: &mut H) {} + let slice = interpreter + .contract + .bytecode + .eof() + .expect("eof") + .data_slice(offset_usize, 32); -pub fn data_copy(interpreter: &mut Interpreter, host: &mut H) {} + 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 = 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); + shared_memory_resize!(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/interpreter.rs b/crates/interpreter/src/interpreter.rs index 4943dbfbb1..1f7522e1d3 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -12,7 +12,7 @@ use crate::{ CreateInputs, CreateOutcome, FunctionStack, Gas, Host, InstructionResult, }; use core::cmp::min; -use revm_primitives::{Bytecode, U256}; +use revm_primitives::{Bytecode, Eof, U256}; use std::borrow::ToOwned; use std::boxed::Box; @@ -151,6 +151,11 @@ impl Interpreter { } } + #[inline] + pub fn eof(&self) -> Option<&Eof> { + self.contract.bytecode.eof() + } + /// Test related helper #[cfg(test)] pub fn new_bytecode(bytecode: Bytecode) -> Self { diff --git a/crates/interpreter/src/interpreter/shared_memory.rs b/crates/interpreter/src/interpreter/shared_memory.rs index b330412418..1d88e0e4d9 100644 --- a/crates/interpreter/src/interpreter/shared_memory.rs +++ b/crates/interpreter/src/interpreter/shared_memory.rs @@ -259,7 +259,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/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index fd19d059cb..faa141be7e 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -51,6 +51,14 @@ 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(_)) diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index d2690ddeb7..64d2abc7de 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -3,11 +3,13 @@ mod decode_helpers; mod header; mod types_section; -use alloy_primitives::Bytes; pub use body::EofBody; pub use header::EofHeader; pub use types_section::TypesSection; +use crate::Bytes; +use std::cmp::min; + #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Eof { @@ -26,6 +28,21 @@ impl Eof { self.raw.clone() } + /// 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(&[]) + } + + pub fn data(&self) -> &[u8] { + &self.body.data_section + } + pub fn decode(raw: Bytes) -> Result { let (header, _) = EofHeader::decode(&raw)?; let body = EofBody::decode(&raw, &header)?; @@ -48,10 +65,25 @@ impl Eof { mod test { use super::*; + use crate::bytes; #[test] fn decode_eof() { let bytes = alloy_primitives::bytes!("ef000101000402000100010400000000800000fe"); Eof::decode(bytes).unwrap(); } + + #[test] + fn data_slice() { + let bytes = alloy_primitives::bytes!("ef000101000402000100010400000000800000fe"); + let mut eof = Eof::decode(bytes).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/legacy/jump_map.rs b/crates/primitives/src/bytecode/legacy/jump_map.rs index bda26738df..89371b50f7 100644 --- a/crates/primitives/src/bytecode/legacy/jump_map.rs +++ b/crates/primitives/src/bytecode/legacy/jump_map.rs @@ -1,10 +1,6 @@ -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}; +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)] From cb3d93a5042c1e71f3816f048af1e1245d0047ce Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 29 Feb 2024 17:54:50 +0100 Subject: [PATCH 14/54] refactor calls --- crates/interpreter/src/call_inputs.rs | 111 ++++++++++++++++ crates/interpreter/src/create_inputs.rs | 51 ++++++++ crates/interpreter/src/gas/calc.rs | 2 +- crates/interpreter/src/gas/constants.rs | 2 + crates/interpreter/src/host.rs | 15 ++- crates/interpreter/src/inner_models.rs | 118 ------------------ .../interpreter/src/instructions/contract.rs | 25 ++-- crates/interpreter/src/instructions/host.rs | 7 +- crates/interpreter/src/instructions/opcode.rs | 10 +- crates/interpreter/src/lib.rs | 8 +- 10 files changed, 204 insertions(+), 145 deletions(-) create mode 100644 crates/interpreter/src/call_inputs.rs create mode 100644 crates/interpreter/src/create_inputs.rs diff --git a/crates/interpreter/src/call_inputs.rs b/crates/interpreter/src/call_inputs.rs new file mode 100644 index 0000000000..0d9063be57 --- /dev/null +++ b/crates/interpreter/src/call_inputs.rs @@ -0,0 +1,111 @@ +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, +} + +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) + } +} + +/// 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, +} diff --git a/crates/interpreter/src/create_inputs.rs b/crates/interpreter/src/create_inputs.rs new file mode 100644 index 0000000000..6119a1b272 --- /dev/null +++ b/crates/interpreter/src/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(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), + } + } +} diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index 092fff7c85..a757fa53ca 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -1,6 +1,6 @@ use super::constants::*; -use crate::inner_models::SelfDestructResult; use crate::primitives::{Address, Spec, SpecId::*, U256}; +use crate::SelfDestructResult; use std::vec::Vec; #[allow(clippy::collapsible_else_if)] diff --git a/crates/interpreter/src/gas/constants.rs b/crates/interpreter/src/gas/constants.rs index 2ba845ac13..9475e3b33a 100644 --- a/crates/interpreter/src/gas/constants.rs +++ b/crates/interpreter/src/gas/constants.rs @@ -37,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 fff18bb848..2e41cf441f 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; @@ -65,3 +62,13 @@ pub struct SStoreResult { /// Is storage slot loaded from database pub is_cold: bool, } + +/// 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/inner_models.rs b/crates/interpreter/src/inner_models.rs index 550fab19c3..7bec10611b 100644 --- a/crates/interpreter/src/inner_models.rs +++ b/crates/interpreter/src/inner_models.rs @@ -3,26 +3,6 @@ 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))] @@ -39,40 +19,6 @@ pub struct CreateInputs { 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 { @@ -104,67 +50,3 @@ impl CreateInputs { } } } - -/// 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/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 4517d8f45c..6a1758f355 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -3,27 +3,32 @@ 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}, + gas::{self, EOF_CREATE_GAS}, interpreter::{Interpreter, InterpreterAction}, - primitives::{Address, Bytes, Log, LogData, Spec, SpecId::*, B256, U256}, + primitives::{Address, Bytes, Spec, SpecId::*, B256, U256}, CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, Host, InstructionResult, Transfer, MAX_INITCODE_SIZE, }; -use core::cmp::min; -use revm_primitives::BLOCK_HASH_HISTORY; -use std::{boxed::Box, vec::Vec}; +use std::boxed::Box; -pub fn create3(interpreter: &mut Interpreter, host: &mut H) {} +pub fn eofcrate(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); -pub fn create4(interpreter: &mut Interpreter, host: &mut H) {} + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; +} + +pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) {} pub fn return_contract(interpreter: &mut Interpreter, host: &mut H) {} -pub fn call2(interpreter: &mut Interpreter, host: &mut H) {} +pub fn extcall(interpreter: &mut Interpreter, host: &mut H) {} -pub fn delegate_call2(interpreter: &mut Interpreter, host: &mut H) {} +pub fn extdcall(interpreter: &mut Interpreter, host: &mut H) {} -pub fn static_call2(interpreter: &mut Interpreter, host: &mut H) {} +pub fn extscall(interpreter: &mut Interpreter, host: &mut H) {} pub fn create( interpreter: &mut Interpreter, diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index 9b69e87477..aa3f6a3f01 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -1,13 +1,12 @@ use crate::{ gas::{self, COLD_ACCOUNT_ACCESS_COST, WARM_STORAGE_READ_COST}, - interpreter::{Interpreter, InterpreterAction}, + interpreter::Interpreter, primitives::{Address, 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); diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index 1d6689d999..db7e53dd03 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -336,8 +336,8 @@ opcodes! { // 0xE9 // 0xEA // 0xEB - 0xEC => CRATE3 => contract::create3::, - 0xED => CREATE4 => contract::create4::, + 0xEC => EOFCREATE => contract::eofcrate::, + 0xED => CREATE4 => contract::txcreate::, 0xEE => RETURNCONTRACT => contract::return_contract::, // 0xEF 0xF0 => CREATE => contract::create::, @@ -348,10 +348,10 @@ opcodes! { 0xF5 => CREATE2 => contract::create::, // 0xF6 0xF7 => RETURNDATALOAD => system::returndataload::, - // 0xF8 - // 0xF9 + 0xF8 => EXTCALL => contract::extcall::, + 0xF9 => EXFCALL => contract::extdcall::, 0xFA => STATICCALL => contract::static_call::, - // 0xFB + 0xFB => EXTSCALL => contract::extscall::, // 0xFC 0xFD => REVERT => control::revert::, 0xFE => INVALID => control::invalid, diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index b0625d6356..b978907dbd 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -12,23 +12,25 @@ extern crate alloc as std; #[macro_use] mod macros; +mod call_inputs; mod call_outcome; +mod create_inputs; mod create_outcome; mod function_stack; pub mod gas; mod host; -mod inner_models; mod instruction_result; pub mod instructions; mod interpreter; // Reexport primary types. +pub use call_inputs::{CallContext, CallInputs, CallScheme, Transfer}; pub use call_outcome::CallOutcome; +pub use create_inputs::{CreateInputs, CreateScheme}; 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, SStoreResult, SelfDestructResult}; pub use instruction_result::*; pub use instructions::{opcode, Instruction, OpCode, OPCODE_JUMPMAP}; pub use interpreter::{ From 1dabca498aa01854a1a116a2652e429b30783ec0 Mon Sep 17 00:00:00 2001 From: rakita Date: Fri, 1 Mar 2024 02:35:10 +0100 Subject: [PATCH 15/54] blueprint for creates --- .../interpreter/src/instructions/contract.rs | 39 ++++++++++++++++++- crates/interpreter/src/instructions/macros.rs | 11 ++++++ crates/interpreter/src/interpreter/stack.rs | 16 ++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 6a1758f355..214e3e8027 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -17,10 +17,47 @@ pub fn eofcrate(interpreter: &mut Interpreter, host: &mut H) { let initcontainer_index = unsafe { *interpreter.instruction_pointer }; pop!(interpreter, value, salt, data_offset, data_size); + let Some(sub_container) = interpreter + .eof() + .expect("EOF is set") + .body + .container_section + .get(initcontainer_index as usize) + else { + // TODO(EOF) handle error + return; + }; + + // Send container for execution container is preverified. + // Create EofCreate() + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; } -pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) {} +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 + ); + // TODO(EOF) get initcode from TxEnv. + let initcode = Bytes::new(); + + // TODO(EOF) deduct gas for validation + gas!(interpreter, 10); + // TODO(EOF) validate initcode, we should do this only once. + // TODO check if data container is full + + // TODO deduct gas for hash of initcode. Should this be done at the start after we got initcode? + + interpreter.next_action = InterpreterAction::None; //Create { inputs: () } + interpreter.instruction_result = InstructionResult::CallOrCreate; +} pub fn return_contract(interpreter: &mut Interpreter, host: &mut H) {} diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index b3997d7deb..2c41b68938 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -125,6 +125,9 @@ macro_rules! pop { ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident) => { 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, ()) + }; } macro_rules! pop_ret { @@ -160,6 +163,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 = InstructionResult::StackUnderflow; + return $ret; + } + // SAFETY: Length is checked above. + let ($x1, $x2, $x3, $x4, $x5) = unsafe { $interp.stack.pop5_unsafe() }; + }; } macro_rules! pop_top { diff --git a/crates/interpreter/src/interpreter/stack.rs b/crates/interpreter/src/interpreter/stack.rs index 59016ef9eb..a9e93d5c15 100644 --- a/crates/interpreter/src/interpreter/stack.rs +++ b/crates/interpreter/src/interpreter/stack.rs @@ -165,6 +165,22 @@ impl Stack { (pop1, pop2, pop3, pop4) } + /// Pops 4 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] From 4354b6df0ad80c822e99d333c29fd1bb8c7d94a2 Mon Sep 17 00:00:00 2001 From: rakita Date: Sat, 2 Mar 2024 02:51:19 +0100 Subject: [PATCH 16/54] eof create inputs --- crates/interpreter/src/eof_create_inputs.rs | 37 +++++++++++++++ crates/interpreter/src/gas/calc.rs | 35 +++++++------- .../interpreter/src/instructions/contract.rs | 47 +++++++++++++++---- crates/interpreter/src/interpreter.rs | 13 +++-- crates/interpreter/src/lib.rs | 2 + crates/primitives/src/bytecode/eof.rs | 7 +++ crates/revm/src/evm.rs | 3 ++ .../src/handler/handle_types/execution.rs | 6 +++ 8 files changed, 122 insertions(+), 28 deletions(-) create mode 100644 crates/interpreter/src/eof_create_inputs.rs diff --git a/crates/interpreter/src/eof_create_inputs.rs b/crates/interpreter/src/eof_create_inputs.rs new file mode 100644 index 0000000000..5d8203d2a0 --- /dev/null +++ b/crates/interpreter/src/eof_create_inputs.rs @@ -0,0 +1,37 @@ +use crate::primitives::{Address, Bytes, Eof, TransactTo, TxEnv, U256}; +use core::ops::Range; +use std::boxed::Box; + +/// Inputs for create call. +#[derive(Debug, Default, Clone)] +pub struct EofCreateInput { + /// Caller of Eof Craate + pub caller: 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, + /// Created address, + pub created_address: Address, +} + +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, + ) -> EofCreateInput { + EofCreateInput { + caller, + value, + eof_init_code, + gas_limit, + created_address, + } + } +} diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index a757fa53ca..3ab0b3b119 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -3,6 +3,7 @@ use crate::primitives::{Address, Spec, SpecId::*, U256}; use crate::SelfDestructResult; use std::vec::Vec; +#[inline] #[allow(clippy::collapsible_else_if)] pub fn sstore_refund(original: U256, current: U256, new: U256) -> i64 { if SPEC::enabled(ISTANBUL) { @@ -55,14 +56,7 @@ pub fn sstore_refund(original: U256, current: U256, new: U256) -> i6 #[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) + CREATE.checked_add(cost_per_word::(len.try_into().ok()?)?) } #[inline] @@ -105,9 +99,7 @@ pub fn exp_cost(power: U256) -> Option { #[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 })?) + VERYLOW.checked_add(cost_per_word::(len)?) } #[inline] @@ -129,6 +121,7 @@ pub fn extcodecopy_cost(len: u64, is_cold: bool) -> Option { base_gas.checked_add(COPY.checked_mul(if wordr == 0 { wordd } else { wordd + 1 })?) } +#[inline] pub fn account_access_gas(is_cold: bool) -> u64 { if SPEC::enabled(BERLIN) { if is_cold { @@ -143,15 +136,22 @@ pub fn account_access_gas(is_cold: bool) -> u64 { } } +#[inline] pub fn log_cost(n: u8, len: u64) -> Option { LOG.checked_add(LOGDATA.checked_mul(len)?)? .checked_add(LOGTOPIC * n as u64) } +#[inline] pub fn keccak256_cost(len: u64) -> Option { + KECCAK256.checked_add(cost_per_word::(len)?) +} + +#[inline] +pub fn cost_per_word(len: u64) -> Option { let wordd = len / 32; let wordr = len % 32; - KECCAK256.checked_add(KECCAK256WORD.checked_mul(if wordr == 0 { wordd } else { wordd + 1 })?) + MULTIPLE.checked_mul(if wordr == 0 { wordd } else { wordd + 1 }) } /// EIP-3860: Limit and meter initcode @@ -161,9 +161,7 @@ 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 } + cost_per_word::(len).unwrap() } #[inline] @@ -185,7 +183,7 @@ pub fn sload_cost(is_cold: bool) -> u64 { } } -#[allow(clippy::collapsible_else_if)] +#[inline] pub fn sstore_cost( original: U256, current: U256, @@ -238,6 +236,7 @@ fn istanbul_sstore_cost( } /// Frontier sstore cost just had two cases set and reset values +#[inline(always)] fn frontier_sstore_cost(current: U256, new: U256) -> u64 { if current == U256::ZERO && new != U256::ZERO { SSTORE_SET @@ -246,6 +245,7 @@ fn frontier_sstore_cost(current: U256, new: U256) -> u64 { } } +#[inline] pub fn selfdestruct_cost(res: SelfDestructResult) -> u64 { // EIP-161: State trie clearing (invariant-preserving alternative) let should_charge_topup = if SPEC::enabled(SPURIOUS_DRAGON) { @@ -271,6 +271,7 @@ pub fn selfdestruct_cost(res: SelfDestructResult) -> u64 { gas } +#[inline] pub fn call_gas(is_cold: bool) -> u64 { if SPEC::enabled(BERLIN) { if is_cold { @@ -286,6 +287,7 @@ pub fn call_gas(is_cold: bool) -> u64 { } } +#[inline] pub fn call_cost( transfers_value: bool, is_new: bool, @@ -344,6 +346,7 @@ 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. +#[inline] pub fn validate_initial_tx_gas( input: &[u8], is_create: bool, diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 214e3e8027..d792d12634 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -3,11 +3,11 @@ mod call_helpers; pub use call_helpers::{calc_call_gas, get_memory_input_and_out_ranges}; use crate::{ - gas::{self, EOF_CREATE_GAS}, + gas::{self, cost_per_word, BASE, EOF_CREATE_GAS, KECCAK256WORD}, interpreter::{Interpreter, InterpreterAction}, - primitives::{Address, Bytes, Spec, SpecId::*, B256, U256}, - CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, Host, InstructionResult, - Transfer, MAX_INITCODE_SIZE, + primitives::{Address, Bytes, Eof, Spec, SpecId::*, B256, U256}, + CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, EofCreateInput, Host, + InstructionResult, Transfer, MAX_INITCODE_SIZE, }; use std::boxed::Box; @@ -48,14 +48,43 @@ pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) { // TODO(EOF) get initcode from TxEnv. let initcode = Bytes::new(); - // TODO(EOF) deduct gas for validation - gas!(interpreter, 10); - // TODO(EOF) validate initcode, we should do this only once. + // deduct gas for validation + gas_or_fail!(interpreter, cost_per_word::(initcode.len() as u64)); + // TODO check if data container is full + 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; + } + + // TODO(EOF) validate initcode, we should do this only once and cache result. - // TODO deduct gas for hash of initcode. Should this be done at the start after we got initcode? + // deduct gas for hash. + gas_or_fail!( + interpreter, + cost_per_word::(initcode.len() as u64) + ); - interpreter.next_action = InterpreterAction::None; //Create { inputs: () } + // TODO(EOF) calculate contract address; + let created_address = Address::ZERO; + + let gas_limit = interpreter.gas().remaining(); + gas!(interpreter, gas_limit); + interpreter.next_action = InterpreterAction::EofCreate { + inputs: Box::new(EofCreateInput::new( + interpreter.contract.address, + created_address, + value, + eof, + gas_limit, + )), + }; interpreter.instruction_result = InstructionResult::CallOrCreate; } diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 1f7522e1d3..cd4843f01b 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -9,7 +9,7 @@ pub use stack::{Stack, STACK_LIMIT}; use crate::{ primitives::Bytes, push, push_b256, return_ok, return_revert, CallInputs, CallOutcome, - CreateInputs, CreateOutcome, FunctionStack, Gas, Host, InstructionResult, + CreateInputs, CreateOutcome, EofCreateInput, FunctionStack, Gas, Host, InstructionResult, }; use core::cmp::min; use revm_primitives::{Bytecode, Eof, U256}; @@ -84,9 +84,16 @@ pub enum InterpreterAction { inputs: Box, }, /// CREATE or CREATE2 instruction called. - Create { inputs: Box }, + Create { + inputs: Box, + }, + EofCreate { + inputs: Box, + }, /// Interpreter finished execution. - Return { result: InterpreterResult }, + Return { + result: InterpreterResult, + }, /// No action #[default] None, diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index b978907dbd..da99379b93 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -16,6 +16,7 @@ mod call_inputs; mod call_outcome; mod create_inputs; mod create_outcome; +mod eof_create_inputs; mod function_stack; pub mod gas; mod host; @@ -27,6 +28,7 @@ mod interpreter; pub use call_inputs::{CallContext, CallInputs, CallScheme, Transfer}; pub use call_outcome::CallOutcome; pub use create_inputs::{CreateInputs, CreateScheme}; +pub use eof_create_inputs::EofCreateInput; pub use create_outcome::CreateOutcome; pub use function_stack::{FunctionReturnFrame, FunctionStack}; pub use gas::Gas; diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index 64d2abc7de..0475004931 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -18,6 +18,13 @@ pub struct Eof { pub raw: Option, } +impl Default for Eof { + fn default() -> Self { + // TODO(EOF) make proper minimal EOF. + Eof::decode("ef000101000402000100010400000000800000fe".into()).unwrap() + } +} + impl Eof { /// Returns len of the header and body in bytes. pub fn len(&self) -> usize { diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index bc857ed1f2..f2443b6948 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -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(); diff --git a/crates/revm/src/handler/handle_types/execution.rs b/crates/revm/src/handler/handle_types/execution.rs index f4300de996..0900fa12b1 100644 --- a/crates/revm/src/handler/handle_types/execution.rs +++ b/crates/revm/src/handler/handle_types/execution.rs @@ -90,6 +90,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: FrameCreateHandle<'a, EXT, DB>, + /// EofCrate return + pub eofcreate_return: FrameCreateReturnHandle<'a, EXT, DB>, + /// Insert EofCreate outcome. + pub insert_eofcreate_outcome: InsertCreateOutcomeHandle<'a, EXT, DB>, } impl<'a, EXT: 'a, DB: Database + 'a> ExecutionHandler<'a, EXT, DB> { From 207ad21c1f8d2a7025177943edda95ebd911e833 Mon Sep 17 00:00:00 2001 From: rakita Date: Mon, 4 Mar 2024 04:08:29 +0100 Subject: [PATCH 17/54] some wip --- crates/interpreter/src/host.rs | 6 ++++ crates/revm/src/evm.rs | 22 ++++++++---- .../src/handler/handle_types/execution.rs | 34 +++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/crates/interpreter/src/host.rs b/crates/interpreter/src/host.rs index 2e41cf441f..df130dff38 100644 --- a/crates/interpreter/src/host.rs +++ b/crates/interpreter/src/host.rs @@ -3,6 +3,12 @@ use crate::primitives::{Address, Bytecode, Env, Log, B256, U256}; mod dummy; pub use dummy::DummyHost; +/* + +Trait as table of opcodes. We dont need that +// We needs static table of opcodes that know what Host we are accessing. +*/ + /// EVM context host. pub trait Host { /// Returns a reference to the environment. diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index f2443b6948..48f7e9cc01 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -1,25 +1,34 @@ use crate::{ builder::{EvmBuilder, HandlerStage, SetGenericStage}, db::{Database, DatabaseCommit, EmptyDB}, - handler::Handler, + handler::{mainnet, Handler}, interpreter::{ opcode::InstructionTables, Host, Interpreter, InterpreterAction, SStoreResult, SelfDestructResult, SharedMemory, }, primitives::{ - specification::SpecId, Address, BlockEnv, Bytecode, CfgEnv, EVMError, EVMResult, Env, - EnvWithHandlerCfg, ExecutionResult, HandlerCfg, Log, ResultAndState, TransactTo, TxEnv, - B256, U256, + specification::BerlinSpec, specification::SpecId, Address, BlockEnv, Bytecode, CfgEnv, + EVMError, EVMResult, Env, EnvWithHandlerCfg, ExecutionResult, HandlerCfg, Log, + ResultAndState, TransactTo, TxEnv, B256, U256, }, Context, ContextWithHandlerCfg, Frame, FrameOrResult, FrameResult, }; use core::fmt; -use revm_interpreter::{CallInputs, CreateInputs}; +use revm_interpreter::{ + opcode::{make_instruction_table, InstructionTable}, + CallInputs, CreateInputs, +}; use std::vec::Vec; /// EVM call stack limit. pub const CALL_STACK_LIMIT: u64 = 1024; +const fn host_instruction_table<'a, EXT, DB: Database>() -> InstructionTable> { + let mut table = make_instruction_table::, BerlinSpec>(); + table[0xf0] = |interpreter, evm| {}; + table +} + /// EVM instance containing both internal EVM context and external context /// and the handler that dictates the logic of EVM (or hardfork specification). pub struct Evm<'a, EXT, DB: Database> { @@ -275,7 +284,8 @@ impl Evm<'_, EXT, DB> { 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)? + //exec.eofcreate(&mut self.context, inputs)? + panic!("test") } InterpreterAction::Return { result } => { // free memory context. diff --git a/crates/revm/src/handler/handle_types/execution.rs b/crates/revm/src/handler/handle_types/execution.rs index 0900fa12b1..42174aaf31 100644 --- a/crates/revm/src/handler/handle_types/execution.rs +++ b/crates/revm/src/handler/handle_types/execution.rs @@ -73,6 +73,37 @@ pub type InsertCreateOutcomeHandle<'a, EXT, DB> = Arc< + 'a, >; +/* + + + + trait NewFrame { + fn new(interpreter, Host) -> Option>; + } + + trait Host { + ... + .. + fn frames(&self) -> Vec>; + } + + trait RunFrame { + fn init_frame(&mut self, Context, shared_memory) -> RunOrReturn {} + + fn run(&mut self, host: Host, instruction_table, shared_memory) -> FrameOrReturn; + + fn insert_result_to_parent(self, parent_interpreter: &mut Interpreter, shared_memory); + + /// Needed for child frame to access it. + fn interpreter(&mut self) -> &mut Interpreter; + + } + + trait FirstFrame { + fn output(&self) -> &FrameResult; + } +*/ + /// Handles related to stack frames. pub struct ExecutionHandler<'a, EXT, DB: Database> { /// Handles last frame return, modified gas for refund and @@ -109,6 +140,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::create::), + eofcreate_return: Arc::new(mainnet::create_return::), + insert_eofcreate_outcome: Arc::new(mainnet::insert_create_outcome), } } } From 2e48462441113f5ba74c218028bbe298d2e5b2cd Mon Sep 17 00:00:00 2001 From: rakita Date: Mon, 4 Mar 2024 07:21:33 +0100 Subject: [PATCH 18/54] add eofcreate structs and exccall flow --- crates/interpreter/src/eof_create_outcome.rs | 69 ++++++++++++ crates/interpreter/src/host.rs | 6 - crates/interpreter/src/interpreter.rs | 5 + crates/interpreter/src/lib.rs | 4 +- crates/revm/src/context.rs | 21 +++- crates/revm/src/evm.rs | 27 +++-- crates/revm/src/frame.rs | 24 +++- .../src/handler/handle_types/execution.rs | 103 ++++++++++++------ crates/revm/src/handler/mainnet.rs | 5 +- crates/revm/src/handler/mainnet/execution.rs | 43 +++++++- crates/revm/src/inspector.rs | 23 +++- crates/revm/src/inspector/handler_register.rs | 10 ++ 12 files changed, 278 insertions(+), 62 deletions(-) create mode 100644 crates/interpreter/src/eof_create_outcome.rs diff --git a/crates/interpreter/src/eof_create_outcome.rs b/crates/interpreter/src/eof_create_outcome.rs new file mode 100644 index 0000000000..4e249b308f --- /dev/null +++ b/crates/interpreter/src/eof_create_outcome.rs @@ -0,0 +1,69 @@ +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: Option
, +} + +impl EofCreateOutcome { + /// Constructs a new `CreateOutcome`. + /// + /// # Arguments + /// + /// * `result` - An `InterpreterResult` representing the result of the interpreter operation. + /// * `address` - An optional `Address` associated with the create operation. + /// + /// # Returns + /// + /// A new `CreateOutcome` instance. + pub fn new(result: InterpreterResult, address: Option
) -> Self { + Self { result, address } + } + + /// 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 + } +} diff --git a/crates/interpreter/src/host.rs b/crates/interpreter/src/host.rs index df130dff38..2e41cf441f 100644 --- a/crates/interpreter/src/host.rs +++ b/crates/interpreter/src/host.rs @@ -3,12 +3,6 @@ use crate::primitives::{Address, Bytecode, Env, Log, B256, U256}; mod dummy; pub use dummy::DummyHost; -/* - -Trait as table of opcodes. We dont need that -// We needs static table of opcodes that know what Host we are accessing. -*/ - /// EVM context host. pub trait Host { /// Returns a reference to the environment. diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index cd4843f01b..b024a97c73 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -7,6 +7,7 @@ pub use contract::Contract; pub use shared_memory::{next_multiple_of_32, SharedMemory}; pub use stack::{Stack, STACK_LIMIT}; +use crate::EofCreateOutcome; use crate::{ primitives::Bytes, push, push_b256, return_ok, return_revert, CallInputs, CallOutcome, CreateInputs, CreateOutcome, EofCreateInput, FunctionStack, Gas, Host, InstructionResult, @@ -250,6 +251,10 @@ impl Interpreter { } } + pub fn insert_eofcreate_outcome(&mut self, create_outcome: EofCreateOutcome) { + // TODO(EOF) + } + /// Inserts the outcome of a call into the virtual machine's state. /// /// This function takes the result of a call, represented by `CallOutcome`, diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index da99379b93..8c61177b6e 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -17,6 +17,7 @@ mod call_outcome; mod create_inputs; mod create_outcome; mod eof_create_inputs; +mod eof_create_outcome; mod function_stack; pub mod gas; mod host; @@ -28,8 +29,9 @@ mod interpreter; pub use call_inputs::{CallContext, CallInputs, CallScheme, Transfer}; pub use call_outcome::CallOutcome; pub use create_inputs::{CreateInputs, CreateScheme}; -pub use eof_create_inputs::EofCreateInput; pub use create_outcome::CreateOutcome; +pub use eof_create_inputs::EofCreateInput; +pub use eof_create_outcome::EofCreateOutcome; pub use function_stack::{FunctionReturnFrame, FunctionStack}; pub use gas::Gas; pub use host::{DummyHost, Host, SStoreResult, SelfDestructResult}; diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index f53f679128..a212816ed7 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -12,7 +12,7 @@ use crate::{ }, FrameOrResult, JournalCheckpoint, CALL_STACK_LIMIT, }; -use revm_interpreter::SStoreResult; +use revm_interpreter::{EofCreateInput, SStoreResult}; use std::boxed::Box; /// Main Context structure that contains both EvmContext and External context. @@ -274,6 +274,16 @@ impl EvmContext { self.journaled_state.tstore(address, index, value) } + /// Make create frame. + #[inline] + pub fn make_eofcreate_frame( + &mut self, + spec_id: SpecId, + inputs: &EofCreateInput, + ) -> Result> { + unimplemented!("TODO(EOF) make_eofcreate_frame") + } + /// Make create frame. #[inline] pub fn make_create_frame( @@ -496,6 +506,15 @@ impl EvmContext { } } + pub fn eofcreate_return( + &mut self, + interpreter_result: &mut InterpreterResult, + address: Address, + journal_checkpoint: JournalCheckpoint, + ) { + unimplemented!("TODO(EOF) eofcreate_return") + } + /// Handles create return. #[inline] pub fn create_return( diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 48f7e9cc01..ded3901cf4 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -1,34 +1,25 @@ use crate::{ builder::{EvmBuilder, HandlerStage, SetGenericStage}, db::{Database, DatabaseCommit, EmptyDB}, - handler::{mainnet, Handler}, + handler::Handler, interpreter::{ opcode::InstructionTables, Host, Interpreter, InterpreterAction, SStoreResult, SelfDestructResult, SharedMemory, }, primitives::{ - specification::BerlinSpec, specification::SpecId, Address, BlockEnv, Bytecode, CfgEnv, - EVMError, EVMResult, Env, EnvWithHandlerCfg, ExecutionResult, HandlerCfg, Log, - ResultAndState, TransactTo, TxEnv, B256, U256, + specification::SpecId, Address, BlockEnv, Bytecode, CfgEnv, EVMError, EVMResult, Env, + EnvWithHandlerCfg, ExecutionResult, HandlerCfg, Log, ResultAndState, TransactTo, TxEnv, + B256, U256, }, Context, ContextWithHandlerCfg, Frame, FrameOrResult, FrameResult, }; use core::fmt; -use revm_interpreter::{ - opcode::{make_instruction_table, InstructionTable}, - CallInputs, CreateInputs, -}; +use revm_interpreter::{CallInputs, CreateInputs}; use std::vec::Vec; /// EVM call stack limit. pub const CALL_STACK_LIMIT: u64 = 1024; -const fn host_instruction_table<'a, EXT, DB: Database>() -> InstructionTable> { - let mut table = make_instruction_table::, BerlinSpec>(); - table[0xf0] = |interpreter, evm| {}; - table -} - /// EVM instance containing both internal EVM context and external context /// and the handler that dictates the logic of EVM (or hardfork specification). pub struct Evm<'a, EXT, DB: Database> { @@ -306,6 +297,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"), @@ -335,6 +330,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)? + } } } } diff --git a/crates/revm/src/frame.rs b/crates/revm/src/frame.rs index ad5eada494..1a8fe39a50 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,13 @@ pub struct CreateFrame { pub frame_data: FrameData, } +/// Eof Create Frame. +#[derive(Debug)] +pub struct EofCreateFrame { + pub created_address: Address, + pub frame_data: FrameData, +} + #[derive(Debug)] pub struct FrameData { /// Journal checkpoint @@ -37,11 +46,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 +62,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => outcome.result, FrameResult::Create(outcome) => outcome.result, + FrameResult::EofCreate(outcome) => outcome.result, } } @@ -62,6 +74,9 @@ impl FrameResult { FrameResult::Create(outcome) => { Output::Create(outcome.result.output.clone(), outcome.address) } + FrameResult::EofCreate(outcome) => { + panic!("EofCreateOutcome does not have output"); + } } } @@ -71,6 +86,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 +96,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 +106,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => &outcome.result, FrameResult::Create(outcome) => &outcome.result, + FrameResult::EofCreate(outcome) => &outcome.result, } } @@ -98,6 +116,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => &mut outcome.result, FrameResult::Create(outcome) => &mut outcome.result, + FrameResult::EofCreate(outcome) => &mut outcome.result, } } @@ -169,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, } } @@ -177,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, } } @@ -185,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, } } } diff --git a/crates/revm/src/handler/handle_types/execution.rs b/crates/revm/src/handler/handle_types/execution.rs index 42174aaf31..db92c2d3f7 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,36 +76,34 @@ pub type InsertCreateOutcomeHandle<'a, EXT, DB> = Arc< + 'a, >; -/* - - - - trait NewFrame { - fn new(interpreter, Host) -> Option>; - } - - trait Host { - ... - .. - fn frames(&self) -> Vec>; - } - - trait RunFrame { - fn init_frame(&mut self, Context, shared_memory) -> RunOrReturn {} - - fn run(&mut self, host: Host, instruction_table, shared_memory) -> FrameOrReturn; - - fn insert_result_to_parent(self, parent_interpreter: &mut Interpreter, shared_memory); - - /// Needed for child frame to access it. - fn interpreter(&mut self) -> &mut Interpreter; +/// 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, +>; - trait FirstFrame { - fn output(&self) -> &FrameResult; - } -*/ +/// 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> { @@ -122,11 +123,11 @@ pub struct ExecutionHandler<'a, EXT, DB: Database> { /// Insert create outcome. pub insert_create_outcome: InsertCreateOutcomeHandle<'a, EXT, DB>, /// Frame EofCreate - pub eofcreate: FrameCreateHandle<'a, EXT, DB>, + pub eofcreate: FrameEOFCreateHandle<'a, EXT, DB>, /// EofCrate return - pub eofcreate_return: FrameCreateReturnHandle<'a, EXT, DB>, + pub eofcreate_return: FrameEOFCreateReturnHandle<'a, EXT, DB>, /// Insert EofCreate outcome. - pub insert_eofcreate_outcome: InsertCreateOutcomeHandle<'a, EXT, DB>, + pub insert_eofcreate_outcome: InsertEOFCreateOutcomeHandle<'a, EXT, DB>, } impl<'a, EXT: 'a, DB: Database + 'a> ExecutionHandler<'a, EXT, DB> { @@ -140,9 +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::create::), - eofcreate_return: Arc::new(mainnet::create_return::), - insert_eofcreate_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), } } } @@ -222,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 7ecf8228c6..af2cedd231 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, @@ -9,7 +10,7 @@ use crate::{ }; use std::boxed::Box; -use revm_interpreter::{CallOutcome, InterpreterResult}; +use revm_interpreter::{CallOutcome, EofCreateInput, EofCreateOutcome, InterpreterResult}; /// Helper function called inside [`last_frame_return`] #[inline] @@ -136,6 +137,46 @@ 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, + Some(frame.created_address), + )) +} + +#[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 revm_interpreter::{primitives::CancunSpec, InterpreterResult}; diff --git a/crates/revm/src/inspector.rs b/crates/revm/src/inspector.rs index dbbd1876c9..cd295a95e2 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/handler_register.rs b/crates/revm/src/inspector/handler_register.rs index d0c8b721cf..85a8609d8c 100644 --- a/crates/revm/src/inspector/handler_register.rs +++ b/crates/revm/src/inspector/handler_register.rs @@ -131,6 +131,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 handle let create_input_stack_inner = create_input_stack.clone(); @@ -179,6 +180,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(); @@ -200,6 +203,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| { @@ -213,6 +218,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()); + } } //inspector.last_frame_return(ctx, frame_result); old_handle(ctx, frame_result) From 48abbe66c857e91b34832b51852bf4e47de4a657 Mon Sep 17 00:00:00 2001 From: rakita Date: Mon, 4 Mar 2024 15:47:51 +0100 Subject: [PATCH 19/54] wip eofcreate code flow and handlers --- crates/interpreter/src/eof_create_inputs.rs | 24 +++--- crates/interpreter/src/eof_create_outcome.rs | 31 +++++-- .../interpreter/src/instructions/contract.rs | 81 +++++++++++++++++-- crates/interpreter/src/instructions/opcode.rs | 2 +- crates/interpreter/src/interpreter.rs | 10 +-- crates/interpreter/src/lib.rs | 4 +- crates/revm/src/context.rs | 73 ++++++++++++++++- crates/revm/src/evm.rs | 11 ++- crates/revm/src/frame.rs | 57 +++++++++---- .../src/handler/handle_types/execution.rs | 26 +++--- crates/revm/src/handler/mainnet/execution.rs | 17 ++-- crates/revm/src/inspector.rs | 12 +-- crates/revm/src/inspector/handler_register.rs | 2 +- 13 files changed, 266 insertions(+), 84 deletions(-) diff --git a/crates/interpreter/src/eof_create_inputs.rs b/crates/interpreter/src/eof_create_inputs.rs index 5d8203d2a0..f5e5cecda0 100644 --- a/crates/interpreter/src/eof_create_inputs.rs +++ b/crates/interpreter/src/eof_create_inputs.rs @@ -1,37 +1,41 @@ -use crate::primitives::{Address, Bytes, Eof, TransactTo, TxEnv, U256}; +use crate::primitives::{Address, Eof, U256}; use core::ops::Range; -use std::boxed::Box; /// Inputs for create call. #[derive(Debug, Default, Clone)] -pub struct EofCreateInput { +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, - /// Created address, - pub created_address: Address, + /// Return memory range. If EOF creation Reverts it can return the + /// the memmory range. + pub return_memory_range: Range, } -impl EofCreateInput { - /// Returns a new instance of EofCreateInput. +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, - ) -> EofCreateInput { - EofCreateInput { + return_memory_range: Range, + ) -> EOFCreateInput { + EOFCreateInput { caller, + created_address, value, eof_init_code, gas_limit, - created_address, + return_memory_range, } } } diff --git a/crates/interpreter/src/eof_create_outcome.rs b/crates/interpreter/src/eof_create_outcome.rs index 4e249b308f..754a29e913 100644 --- a/crates/interpreter/src/eof_create_outcome.rs +++ b/crates/interpreter/src/eof_create_outcome.rs @@ -1,3 +1,5 @@ +use core::ops::Range; + use crate::{Gas, InstructionResult, InterpreterResult}; use revm_primitives::{Address, Bytes}; @@ -6,14 +8,16 @@ 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)] -pub struct EofCreateOutcome { - // The result of the interpreter operation. +pub struct EOFCreateOutcome { + /// The result of the interpreter operation. pub result: InterpreterResult, - // An optional address associated with the create operation. - pub address: Option
, + /// 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 { +impl EOFCreateOutcome { /// Constructs a new `CreateOutcome`. /// /// # Arguments @@ -24,8 +28,16 @@ impl EofCreateOutcome { /// # Returns /// /// A new `CreateOutcome` instance. - pub fn new(result: InterpreterResult, address: Option
) -> Self { - Self { result, address } + 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`. @@ -66,4 +78,9 @@ impl EofCreateOutcome { 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/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index d792d12634..c0f8017afa 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -1,17 +1,36 @@ mod call_helpers; pub use call_helpers::{calc_call_gas, get_memory_input_and_out_ranges}; +use revm_primitives::keccak256; use crate::{ gas::{self, cost_per_word, BASE, EOF_CREATE_GAS, KECCAK256WORD}, interpreter::{Interpreter, InterpreterAction}, primitives::{Address, Bytes, Eof, Spec, SpecId::*, B256, U256}, - CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, EofCreateInput, Host, + CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, EOFCreateInput, Host, InstructionResult, Transfer, MAX_INITCODE_SIZE, }; +use core::ops::Range; use std::boxed::Box; -pub fn eofcrate(interpreter: &mut Interpreter, host: &mut H) { +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); + shared_memory_resize!(interpreter, offset, len, None); + // range is checked in shared_memory_resize! 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) + } +} + +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 }; @@ -23,18 +42,51 @@ pub fn eofcrate(interpreter: &mut Interpreter, host: &mut H) { .body .container_section .get(initcontainer_index as usize) + .cloned() else { // TODO(EOF) handle error return; }; + // 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) + ); + + let created_address = interpreter + .contract + .caller + .create2(salt.to_be_bytes(), keccak256(sub_container)); + // Send container for execution container is preverified. - // Create EofCreate() + interpreter.next_action = InterpreterAction::EOFCreate { + inputs: Box::new(EOFCreateInput::new( + interpreter.contract.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) { +pub fn txcreate(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, EOF_CREATE_GAS); pop!( @@ -45,6 +97,13 @@ pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) { data_offset, data_size ); + // TODO(EOF) check when memory resize should be done + let Some(return_range) = resize_memory(interpreter, data_offset, data_size) else { + return; + }; + + let tx_initcode_hash = B256::from(tx_initcode_hash); + // TODO(EOF) get initcode from TxEnv. let initcode = Bytes::new(); @@ -71,18 +130,24 @@ pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) { cost_per_word::(initcode.len() as u64) ); - // TODO(EOF) calculate contract address; - let created_address = Address::ZERO; + // Create new address + let created_address = interpreter + .contract + .caller + .create2(salt.to_be_bytes(), tx_initcode_hash); let gas_limit = interpreter.gas().remaining(); + // spend all gas and reimburse it after call ends. gas!(interpreter, gas_limit); - interpreter.next_action = InterpreterAction::EofCreate { - inputs: Box::new(EofCreateInput::new( + + interpreter.next_action = InterpreterAction::EOFCreate { + inputs: Box::new(EOFCreateInput::new( interpreter.contract.address, created_address, value, eof, gas_limit, + return_range, )), }; interpreter.instruction_result = InstructionResult::CallOrCreate; diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index 404e5754d9..dae00551c4 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -359,7 +359,7 @@ opcodes! { // 0xE9 // 0xEA // 0xEB - 0xEC => EOFCREATE => contract::eofcrate::, + 0xEC => EOFCREATE => contract::eofcreate::, 0xED => CREATE4 => contract::txcreate::, 0xEE => RETURNCONTRACT => contract::return_contract::, // 0xEF diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index b024a97c73..451e707025 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -7,10 +7,10 @@ pub use contract::Contract; pub use shared_memory::{next_multiple_of_32, SharedMemory}; pub use stack::{Stack, STACK_LIMIT}; -use crate::EofCreateOutcome; +use crate::EOFCreateOutcome; use crate::{ primitives::Bytes, push, push_b256, return_ok, return_revert, CallInputs, CallOutcome, - CreateInputs, CreateOutcome, EofCreateInput, FunctionStack, Gas, Host, InstructionResult, + CreateInputs, CreateOutcome, EOFCreateInput, FunctionStack, Gas, Host, InstructionResult, }; use core::cmp::min; use revm_primitives::{Bytecode, Eof, U256}; @@ -88,8 +88,8 @@ pub enum InterpreterAction { Create { inputs: Box, }, - EofCreate { - inputs: Box, + EOFCreate { + inputs: Box, }, /// Interpreter finished execution. Return { @@ -251,7 +251,7 @@ impl Interpreter { } } - pub fn insert_eofcreate_outcome(&mut self, create_outcome: EofCreateOutcome) { + pub fn insert_eofcreate_outcome(&mut self, create_outcome: EOFCreateOutcome) { // TODO(EOF) } diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index 8c61177b6e..4d004aabe0 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -30,8 +30,8 @@ pub use call_inputs::{CallContext, CallInputs, CallScheme, Transfer}; 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; +pub use eof_create_inputs::EOFCreateInput; +pub use eof_create_outcome::EOFCreateOutcome; pub use function_stack::{FunctionReturnFrame, FunctionStack}; pub use gas::Gas; pub use host::{DummyHost, Host, SStoreResult, SelfDestructResult}; diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index a212816ed7..84e06adfeb 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -12,7 +12,7 @@ use crate::{ }, FrameOrResult, JournalCheckpoint, CALL_STACK_LIMIT, }; -use revm_interpreter::{EofCreateInput, SStoreResult}; +use revm_interpreter::{EOFCreateInput, SStoreResult}; use std::boxed::Box; /// Main Context structure that contains both EvmContext and External context. @@ -275,13 +275,80 @@ impl EvmContext { } /// Make create frame. + /// TODO(EOF) refactor with crate function. #[inline] pub fn make_eofcreate_frame( &mut self, spec_id: SpecId, - inputs: &EofCreateInput, + inputs: &EOFCreateInput, ) -> Result> { - unimplemented!("TODO(EOF) make_eofcreate_frame") + // Prepare crate. + let gas = Gas::new(inputs.gas_limit); + + let return_error = |e| { + Ok(FrameOrResult::new_eofcreate_result( + InterpreterResult { + result: e, + gas, + 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() { + 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 = Box::new(Contract::new( + Bytes::new(), + Bytecode::Eof(inputs.eof_init_code.clone()), + None, + inputs.created_address, + inputs.caller, + inputs.value, + )); + + // TODO(eof) flag. + + Ok(FrameOrResult::new_eofcreate_frame( + inputs.created_address, + inputs.return_memory_range.clone(), + checkpoint, + Interpreter::new(contract, gas.limit(), false), + )) } /// Make create frame. diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index ded3901cf4..67ea103c4a 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -274,9 +274,8 @@ 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)? - panic!("test") + InterpreterAction::EOFCreate { inputs } => { + exec.eofcreate(&mut self.context, inputs)? } InterpreterAction::Return { result } => { // free memory context. @@ -297,9 +296,9 @@ impl Evm<'_, EXT, DB> { // return_create FrameResult::Create(exec.create_return(ctx, frame, result)?) } - Frame::EofCreate(frame) => { + Frame::EOFCreate(frame) => { // return_eofcreate - FrameResult::EofCreate(exec.eofcreate_return(ctx, frame, result)?) + FrameResult::EOFCreate(exec.eofcreate_return(ctx, frame, result)?) } }) } @@ -330,7 +329,7 @@ impl Evm<'_, EXT, DB> { // return_create exec.insert_create_outcome(ctx, stack_frame, outcome)? } - FrameResult::EofCreate(outcome) => { + FrameResult::EOFCreate(outcome) => { // return_eofcreate exec.insert_eofcreate_outcome(ctx, stack_frame, outcome)? } diff --git a/crates/revm/src/frame.rs b/crates/revm/src/frame.rs index 1a8fe39a50..bb6c035094 100644 --- a/crates/revm/src/frame.rs +++ b/crates/revm/src/frame.rs @@ -5,7 +5,7 @@ use crate::{ }; use core::ops::Range; use revm_interpreter::{ - CallOutcome, CreateOutcome, EofCreateOutcome, Gas, InstructionResult, InterpreterResult, + CallOutcome, CreateOutcome, EOFCreateOutcome, Gas, InstructionResult, InterpreterResult, }; use std::boxed::Box; @@ -28,8 +28,9 @@ pub struct CreateFrame { /// Eof Create Frame. #[derive(Debug)] -pub struct EofCreateFrame { +pub struct EOFCreateFrame { pub created_address: Address, + pub return_memory_range: Range, pub frame_data: FrameData, } @@ -46,13 +47,13 @@ pub struct FrameData { pub enum Frame { Call(Box), Create(Box), - EofCreate(Box), + EOFCreate(Box), } pub enum FrameResult { Call(CallOutcome), Create(CreateOutcome), - EofCreate(EofCreateOutcome), + EOFCreate(EOFCreateOutcome), } impl FrameResult { @@ -62,7 +63,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => outcome.result, FrameResult::Create(outcome) => outcome.result, - FrameResult::EofCreate(outcome) => outcome.result, + FrameResult::EOFCreate(outcome) => outcome.result, } } @@ -74,8 +75,8 @@ impl FrameResult { FrameResult::Create(outcome) => { Output::Create(outcome.result.output.clone(), outcome.address) } - FrameResult::EofCreate(outcome) => { - panic!("EofCreateOutcome does not have output"); + FrameResult::EOFCreate(outcome) => { + panic!("EOFCreateOutcome does not have output"); } } } @@ -86,7 +87,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => &outcome.result.gas, FrameResult::Create(outcome) => &outcome.result.gas, - FrameResult::EofCreate(outcome) => &outcome.result.gas, + FrameResult::EOFCreate(outcome) => &outcome.result.gas, } } @@ -96,7 +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, + FrameResult::EOFCreate(outcome) => &mut outcome.result.gas, } } @@ -106,7 +107,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => &outcome.result, FrameResult::Create(outcome) => &outcome.result, - FrameResult::EofCreate(outcome) => &outcome.result, + FrameResult::EOFCreate(outcome) => &outcome.result, } } @@ -116,7 +117,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => &mut outcome.result, FrameResult::Create(outcome) => &mut outcome.result, - FrameResult::EofCreate(outcome) => &mut outcome.result, + FrameResult::EOFCreate(outcome) => &mut outcome.result, } } @@ -188,7 +189,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, + Frame::EOFCreate(eof_create_frame) => eof_create_frame.frame_data, } } @@ -197,7 +198,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, + Self::EOFCreate(eof_create_frame) => &eof_create_frame.frame_data, } } @@ -206,7 +207,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, + Self::EOFCreate(eof_create_frame) => &mut eof_create_frame.frame_data, } } } @@ -221,6 +222,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, @@ -245,6 +262,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 db92c2d3f7..d13dd2057a 100644 --- a/crates/revm/src/handler/handle_types/execution.rs +++ b/crates/revm/src/handler/handle_types/execution.rs @@ -1,5 +1,5 @@ use crate::{ - frame::EofCreateFrame, + frame::EOFCreateFrame, handler::mainnet, interpreter::{CallInputs, CreateInputs, SharedMemory}, primitives::{db::Database, EVMError, Spec}, @@ -8,7 +8,7 @@ use crate::{ use std::{boxed::Box, sync::Arc}; use revm_interpreter::{ - CallOutcome, CreateOutcome, EofCreateInput, EofCreateOutcome, InterpreterResult, + CallOutcome, CreateOutcome, EOFCreateInput, EOFCreateOutcome, InterpreterResult, }; /// Handles first frame return handle. @@ -80,7 +80,7 @@ pub type InsertCreateOutcomeHandle<'a, EXT, DB> = Arc< pub type FrameEOFCreateHandle<'a, EXT, DB> = Arc< dyn Fn( &mut Context, - Box, + Box, ) -> Result::Error>> + 'a, >; @@ -89,9 +89,9 @@ pub type FrameEOFCreateHandle<'a, EXT, DB> = Arc< pub type FrameEOFCreateReturnHandle<'a, EXT, DB> = Arc< dyn Fn( &mut Context, - Box, + Box, InterpreterResult, - ) -> Result::Error>> + ) -> Result::Error>> + 'a, >; @@ -100,7 +100,7 @@ pub type InsertEOFCreateOutcomeHandle<'a, EXT, DB> = Arc< dyn Fn( &mut Context, &mut Frame, - EofCreateOutcome, + EOFCreateOutcome, ) -> Result<(), EVMError<::Error>> + 'a, >; @@ -122,11 +122,11 @@ 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 + /// Frame EOFCreate pub eofcreate: FrameEOFCreateHandle<'a, EXT, DB>, - /// EofCrate return + /// EOFCreate return pub eofcreate_return: FrameEOFCreateReturnHandle<'a, EXT, DB>, - /// Insert EofCreate outcome. + /// Insert EOFCreate outcome. pub insert_eofcreate_outcome: InsertEOFCreateOutcomeHandle<'a, EXT, DB>, } @@ -229,7 +229,7 @@ impl<'a, EXT, DB: Database> ExecutionHandler<'a, EXT, DB> { pub fn eofcreate( &self, context: &mut Context, - inputs: Box, + inputs: Box, ) -> Result> { (self.eofcreate)(context, inputs) } @@ -239,9 +239,9 @@ impl<'a, EXT, DB: Database> ExecutionHandler<'a, EXT, DB> { pub fn eofcreate_return( &self, context: &mut Context, - frame: Box, + frame: Box, interpreter_result: InterpreterResult, - ) -> Result> { + ) -> Result> { (self.eofcreate_return)(context, frame, interpreter_result) } @@ -251,7 +251,7 @@ impl<'a, EXT, DB: Database> ExecutionHandler<'a, EXT, DB> { &self, context: &mut Context, frame: &mut Frame, - outcome: EofCreateOutcome, + outcome: EOFCreateOutcome, ) -> Result<(), EVMError> { (self.insert_eofcreate_outcome)(context, frame, outcome) } diff --git a/crates/revm/src/handler/mainnet/execution.rs b/crates/revm/src/handler/mainnet/execution.rs index af2cedd231..f4f1f7b2c0 100644 --- a/crates/revm/src/handler/mainnet/execution.rs +++ b/crates/revm/src/handler/mainnet/execution.rs @@ -1,6 +1,6 @@ use crate::{ db::Database, - frame::EofCreateFrame, + frame::EOFCreateFrame, interpreter::{ return_ok, return_revert, CallInputs, CreateInputs, CreateOutcome, Gas, InstructionResult, SharedMemory, @@ -10,7 +10,7 @@ use crate::{ }; use std::boxed::Box; -use revm_interpreter::{CallOutcome, EofCreateInput, EofCreateOutcome, InterpreterResult}; +use revm_interpreter::{CallOutcome, EOFCreateInput, EOFCreateOutcome, InterpreterResult}; /// Helper function called inside [`last_frame_return`] #[inline] @@ -141,7 +141,7 @@ pub fn insert_create_outcome( #[inline] pub fn eofcreate( context: &mut Context, - inputs: Box, + inputs: Box, ) -> Result> { context.evm.make_eofcreate_frame(SPEC::SPEC_ID, &inputs) } @@ -149,17 +149,18 @@ pub fn eofcreate( #[inline] pub fn eofcreate_return( context: &mut Context, - frame: Box, + frame: Box, mut interpreter_result: InterpreterResult, -) -> Result> { +) -> Result> { context.evm.eofcreate_return::( &mut interpreter_result, frame.created_address, frame.frame_data.checkpoint, ); - Ok(EofCreateOutcome::new( + Ok(EOFCreateOutcome::new( interpreter_result, - Some(frame.created_address), + frame.created_address, + frame.return_memory_range, )) } @@ -167,7 +168,7 @@ pub fn eofcreate_return( pub fn insert_eofcreate_outcome( context: &mut Context, frame: &mut Frame, - outcome: EofCreateOutcome, + outcome: EOFCreateOutcome, ) -> Result<(), EVMError> { core::mem::replace(&mut context.evm.error, Ok(()))?; frame diff --git a/crates/revm/src/inspector.rs b/crates/revm/src/inspector.rs index cd295a95e2..170a42cd26 100644 --- a/crates/revm/src/inspector.rs +++ b/crates/revm/src/inspector.rs @@ -1,5 +1,5 @@ use crate::{ - interpreter::{CallInputs, CreateInputs, EofCreateInput, EofCreateOutcome, Interpreter}, + interpreter::{CallInputs, CreateInputs, EOFCreateInput, EOFCreateOutcome, Interpreter}, primitives::{db::Database, Address, Log, U256}, EvmContext, }; @@ -138,8 +138,8 @@ pub trait Inspector { fn eofcreate( &mut self, context: &mut EvmContext, - inputs: &mut EofCreateInput, - ) -> Option { + inputs: &mut EOFCreateInput, + ) -> Option { let _ = context; let _ = inputs; None @@ -148,9 +148,9 @@ pub trait Inspector { fn eofcreate_end( &mut self, context: &mut EvmContext, - inputs: &EofCreateInput, - outcome: EofCreateOutcome, - ) -> EofCreateOutcome { + inputs: &EOFCreateInput, + outcome: EOFCreateOutcome, + ) -> EOFCreateOutcome { let _ = context; let _ = inputs; outcome diff --git a/crates/revm/src/inspector/handler_register.rs b/crates/revm/src/inspector/handler_register.rs index 85a8609d8c..ccd2dc545a 100644 --- a/crates/revm/src/inspector/handler_register.rs +++ b/crates/revm/src/inspector/handler_register.rs @@ -218,7 +218,7 @@ 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) => { + FrameResult::EOFCreate(outcome) => { let eofcreate_inputs = eofcreate_input_stack.borrow_mut().pop().unwrap(); *outcome = inspector.eofcreate_end(&mut ctx.evm, &eofcreate_inputs, outcome.clone()); From 9d8f612e42b495f17b09769eff4915653b160e89 Mon Sep 17 00:00:00 2001 From: rakita Date: Mon, 4 Mar 2024 18:11:47 +0100 Subject: [PATCH 20/54] fix tests --- crates/interpreter/src/instruction_result.rs | 2 +- crates/interpreter/src/instructions/contract.rs | 16 ++++++++++++---- crates/interpreter/src/instructions/stack.rs | 3 +++ crates/interpreter/src/instructions/system.rs | 4 +++- crates/interpreter/src/interpreter/analysis.rs | 7 +++++-- crates/primitives/src/bytecode.rs | 2 +- 6 files changed, 25 insertions(+), 9 deletions(-) diff --git a/crates/interpreter/src/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index f6c8bef6fe..366a34a666 100644 --- a/crates/interpreter/src/instruction_result.rs +++ b/crates/interpreter/src/instruction_result.rs @@ -271,7 +271,7 @@ impl From for SuccessOrHalt { // TODO(EOF) Check how to propagate error that should be a EVM panic! InstructionResult::OpcodeDisabledInEof => Self::FatalExternalError, // TODO(EOF) make proper error - InstructionResult::EOFOpcodeDisabledInLegacy => Self::FatalExternalError, + InstructionResult::EOFOpcodeDisabledInLegacy => Self::Halt(HaltReason::OpcodeNotFound), // TODO(EOF) InstructionResult::EOFFunctionStackOverflow => Self::FatalExternalError, // TODO(EOF) diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index c0f8017afa..c875bd115c 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -153,13 +153,21 @@ pub fn txcreate(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn return_contract(interpreter: &mut Interpreter, host: &mut H) {} +pub fn return_contract(interpreter: &mut Interpreter, host: &mut H) { + error_on_disabled_eof!(interpreter); +} -pub fn extcall(interpreter: &mut Interpreter, host: &mut H) {} +pub fn extcall(interpreter: &mut Interpreter, host: &mut H) { + error_on_disabled_eof!(interpreter); +} -pub fn extdcall(interpreter: &mut Interpreter, host: &mut H) {} +pub fn extdcall(interpreter: &mut Interpreter, host: &mut H) { + error_on_disabled_eof!(interpreter); +} -pub fn extscall(interpreter: &mut Interpreter, host: &mut H) {} +pub fn extscall(interpreter: &mut Interpreter, host: &mut H) { + error_on_disabled_eof!(interpreter); +} pub fn create( interpreter: &mut Interpreter, diff --git a/crates/interpreter/src/instructions/stack.rs b/crates/interpreter/src/instructions/stack.rs index bb21ddf2fe..29b7262ec0 100644 --- a/crates/interpreter/src/instructions/stack.rs +++ b/crates/interpreter/src/instructions/stack.rs @@ -52,6 +52,7 @@ pub fn swap(interpreter: &mut Interpreter, _host: &mut } 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) { @@ -61,6 +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); gas!(interpreter, gas::VERYLOW); let imm = unsafe { *interpreter.instruction_pointer }; if let Err(result) = interpreter.stack.swap(imm as usize + 1) { @@ -70,6 +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); 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 4aeb9af7ea..3f9acf8dca 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -134,7 +134,9 @@ pub fn returndatacopy(interpreter: &mut Interpreter, _host: } } -pub fn returndataload(interpreter: &mut Interpreter, _host: &mut H) {} +pub fn returndataload(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); +} pub fn gas(interpreter: &mut Interpreter, _host: &mut H) { panic_on_eof!(interpreter); diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 60305ffc53..70500ca2b6 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -1,4 +1,4 @@ -use revm_primitives::LegacyAnalyzedBytecode; +use revm_primitives::{Bytes, LegacyAnalyzedBytecode}; use crate::opcode; use crate::primitives::{ @@ -18,7 +18,10 @@ pub fn to_analysed(bytecode: Bytecode) -> Bytecode { let (bytes, len) = match bytecode { Bytecode::LegacyRaw(bytecode) => { let len = bytecode.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) } n => return n, }; diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index faa141be7e..72d43deecf 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -94,7 +94,7 @@ impl Bytecode { pub fn bytecode_bytes(&self) -> Bytes { match self { Self::LegacyRaw(bytes) => bytes.clone(), - Self::LegacyAnalyzed(analyzed) => analyzed.original_bytes(), + Self::LegacyAnalyzed(analyzed) => analyzed.bytes(), Self::Eof(eof) => eof .body .code(0) From 0fc345ab7436a284551609d8ea7022c31a814cb9 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 5 Mar 2024 20:04:47 +0100 Subject: [PATCH 21/54] eof creates --- crates/interpreter/src/host.rs | 10 +++- crates/interpreter/src/host/dummy.rs | 6 +- crates/interpreter/src/instruction_result.rs | 4 ++ .../interpreter/src/instructions/contract.rs | 56 ++++++++++++++++++- .../src/instructions/contract/call_helpers.rs | 43 +++++++------- crates/interpreter/src/instructions/opcode.rs | 2 +- crates/interpreter/src/interpreter.rs | 37 +++++++++++- crates/interpreter/src/lib.rs | 2 +- crates/primitives/src/bytecode/eof.rs | 2 +- crates/primitives/src/bytecode/eof/body.rs | 4 +- crates/primitives/src/bytecode/eof/header.rs | 1 + crates/revm/src/context.rs | 36 +++++++++--- crates/revm/src/evm.rs | 6 +- crates/revm/src/journaled_state.rs | 16 ++++-- 14 files changed, 178 insertions(+), 47 deletions(-) diff --git a/crates/interpreter/src/host.rs b/crates/interpreter/src/host.rs index 2e41cf441f..2c0802afbd 100644 --- a/crates/interpreter/src/host.rs +++ b/crates/interpreter/src/host.rs @@ -14,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; @@ -63,6 +63,14 @@ pub struct SStoreResult { pub is_cold: bool, } +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct LoadAccountResult { + /// Is account cold loaded + pub is_cold: bool, + /// Is account new + pub is_not_existing: bool, +} + /// 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))] 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/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index 366a34a666..de93d1cc38 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, + EofCreate, // revert codes Revert = 0x10, // revert opcode @@ -109,6 +110,7 @@ macro_rules! return_ok { | InstructionResult::Stop | InstructionResult::Return | InstructionResult::SelfDestruct + | InstructionResult::EofCreate }; } @@ -229,6 +231,8 @@ impl From for SuccessOrHalt { InstructionResult::Return => Self::Success(SuccessReason::Return), InstructionResult::SelfDestruct => Self::Success(SuccessReason::SelfDestruct), InstructionResult::Revert => Self::Revert, + // TODO EOFCreate is not external opcode. + InstructionResult::EofCreate => Self::FatalExternalError, InstructionResult::CallOrCreate => Self::InternalCallOrCreate, // used only in interpreter loop InstructionResult::CallTooDeep => Self::Halt(HaltReason::CallTooDeep), // not gonna happen for first call InstructionResult::OutOfFunds => Self::Halt(HaltReason::OutOfFunds), // Check for first call is done separately. diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index c875bd115c..3678e40a2f 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -10,7 +10,7 @@ use crate::{ CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, EOFCreateInput, Host, InstructionResult, Transfer, MAX_INITCODE_SIZE, }; -use core::ops::Range; +use core::{cmp::max, ops::Range}; use std::boxed::Box; pub fn resize_memory( @@ -45,6 +45,7 @@ pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) { .cloned() else { // TODO(EOF) handle error + interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; @@ -157,8 +158,59 @@ pub fn return_contract(interpreter: &mut Interpreter, host: &mut H) { error_on_disabled_eof!(interpreter); } -pub fn extcall(interpreter: &mut Interpreter, host: &mut H) { +pub fn extcall(interpreter: &mut Interpreter, host: &mut H) { error_on_disabled_eof!(interpreter); + panic_on_eof!(interpreter); + pop_address!(interpreter, to); + pop!(interpreter, value); + if interpreter.is_static && value != U256::ZERO { + interpreter.instruction_result = InstructionResult::CallNotAllowedInsideStatic; + return; + } + + // TODO(EOF) check if destination is EOF. + 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, + u64::MAX, + true, + true, + ) else { + return; + }; + + let mut gas_limit = max(gas_limit, 5000); + gas!(interpreter, gas_limit); + + // 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 extdcall(interpreter: &mut Interpreter, host: &mut H) { diff --git a/crates/interpreter/src/instructions/contract/call_helpers.rs b/crates/interpreter/src/instructions/contract/call_helpers.rs index fc9509c25d..e3f178f166 100644 --- a/crates/interpreter/src/instructions/contract/call_helpers.rs +++ b/crates/interpreter/src/instructions/contract/call_helpers.rs @@ -43,30 +43,35 @@ pub fn calc_call_gas( is_call_or_callcode: bool, is_call_or_staticcall: bool, ) -> Option { - let Some((is_cold, exist)) = host.load_account(to) else { + let Some(load_result) = host.load_account(to) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return None; }; - let is_new = !exist; + let is_new = !load_result.is_not_existing; - let call_cost = gas::call_cost::( - has_transfer, - is_new, - is_cold, - is_call_or_callcode, - is_call_or_staticcall, - ); + if interpreter.is_eof { + // TODO(EOF) + None + } else { + let call_cost = gas::call_cost::( + has_transfer, + is_new, + load_result.is_cold, + is_call_or_callcode, + is_call_or_staticcall, + ); - gas!(interpreter, call_cost, None); + 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 - }; + // 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) + Some(gas_limit) + } } diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index dae00551c4..4a51ec1757 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -371,7 +371,7 @@ opcodes! { 0xF5 => CREATE2 => contract::create::, // 0xF6 0xF7 => RETURNDATALOAD => system::returndataload::, - 0xF8 => EXTCALL => contract::extcall::, + 0xF8 => EXTCALL => contract::extcall::, 0xF9 => EXFCALL => contract::extdcall::, 0xFA => STATICCALL => contract::static_call::, 0xFB => EXTSCALL => contract::extscall::, diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 451e707025..c51d7a1fb4 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -36,6 +36,8 @@ pub struct Interpreter { /// 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. @@ -152,6 +154,7 @@ impl Interpreter { 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(), @@ -159,6 +162,12 @@ 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() @@ -252,7 +261,33 @@ impl Interpreter { } pub fn insert_eofcreate_outcome(&mut self, create_outcome: EOFCreateOutcome) { - // TODO(EOF) + 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 + Bytes::new() + }; + + match instruction_result { + InstructionResult::EofCreate => { + 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. diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index 4d004aabe0..c589bc1f83 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -34,7 +34,7 @@ pub use eof_create_inputs::EOFCreateInput; pub use eof_create_outcome::EOFCreateOutcome; pub use function_stack::{FunctionReturnFrame, FunctionStack}; pub use gas::Gas; -pub use host::{DummyHost, Host, SStoreResult, SelfDestructResult}; +pub use host::{DummyHost, Host, LoadAccountResult, SStoreResult, SelfDestructResult}; pub use instruction_result::*; pub use instructions::{opcode, Instruction, OpCode, OPCODE_JUMPMAP}; pub use interpreter::{ diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index 0475004931..dcd2bc81c5 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -8,7 +8,7 @@ pub use header::EofHeader; pub use types_section::TypesSection; use crate::Bytes; -use std::cmp::min; +use core::cmp::min; #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/crates/primitives/src/bytecode/eof/body.rs b/crates/primitives/src/bytecode/eof/body.rs index 49aae02218..cbc693ffba 100644 --- a/crates/primitives/src/bytecode/eof/body.rs +++ b/crates/primitives/src/bytecode/eof/body.rs @@ -1,6 +1,6 @@ -use crate::Bytes; - use super::{EofHeader, TypesSection}; +use crate::Bytes; +use std::vec::Vec; #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/crates/primitives/src/bytecode/eof/header.rs b/crates/primitives/src/bytecode/eof/header.rs index b66ccc3d49..a6fc1773b4 100644 --- a/crates/primitives/src/bytecode/eof/header.rs +++ b/crates/primitives/src/bytecode/eof/header.rs @@ -1,4 +1,5 @@ use super::decode_helpers::{consume_u16, consume_u8}; +use std::vec::Vec; /// EOF Header containing #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index 84e06adfeb..937d7a043a 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -2,13 +2,13 @@ use crate::{ db::{Database, EmptyDB}, interpreter::{ analysis::to_analysed, gas, return_ok, CallInputs, Contract, CreateInputs, Gas, - InstructionResult, Interpreter, InterpreterResult, MAX_CODE_SIZE, + InstructionResult, Interpreter, InterpreterResult, MAX_CODE_SIZE, LoadAccountResult, }, journaled_state::JournaledState, precompile::{Precompile, Precompiles}, primitives::{ - keccak256, Address, AnalysisKind, Bytecode, Bytes, CreateScheme, EVMError, Env, HandlerCfg, - HashSet, Spec, SpecId, SpecId::*, B256, U256, + keccak256, Address, AnalysisKind, Bytecode, Bytes, CreateScheme, EVMError, Env, Eof, + HandlerCfg, HashSet, Spec, SpecId, SpecId::*, B256, U256, }, FrameOrResult, JournalCheckpoint, CALL_STACK_LIMIT, }; @@ -208,7 +208,7 @@ impl EvmContext { /// Load account and return flags (is_cold, exists) #[inline] - pub fn load_account(&mut self, address: Address) -> Result<(bool, bool), EVMError> { + pub fn load_account(&mut self, address: Address) -> Result> { self.journaled_state .load_account_exist(address, &mut self.db) } @@ -340,14 +340,16 @@ impl EvmContext { inputs.caller, inputs.value, )); - - // TODO(eof) flag. + + let mut interpreter = Interpreter::new(contract, gas.limit(), false); + // EOF init will enabled RETURNCONTRACT opcode. + interpreter.set_is_eof_init(); Ok(FrameOrResult::new_eofcreate_frame( inputs.created_address, inputs.return_memory_range.clone(), checkpoint, - Interpreter::new(contract, gas.limit(), false), + interpreter, )) } @@ -573,13 +575,31 @@ impl EvmContext { } } + /// 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, ) { - unimplemented!("TODO(EOF) eofcreate_return") + if interpreter_result.result != InstructionResult::EofCreate { + self.journaled_state.checkpoint_revert(journal_checkpoint); + return; + } + // Note that we still execute Return opcode and return the bytes. + // In EOF those opcodes should abort execution. + // For Return that returns bytes is okay as gas is still protecting us from ddos + // and if it fails on oog, behaviour will be same as if it failed on return. + + // commit changes reduces depth by -1. + self.journaled_state.checkpoint_commit(); + + let bytecode = + Eof::decode(interpreter_result.output.clone()).expect("Eof is already verified"); + self.journaled_state + .set_code(address, Bytecode::Eof(bytecode)); + + interpreter_result.result = InstructionResult::Return; } /// Handles create return. diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 67ea103c4a..4e88491e28 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, @@ -408,7 +408,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(address) diff --git a/crates/revm/src/journaled_state.rs b/crates/revm/src/journaled_state.rs index f0c2c9c8fb..1ae8ac30be 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. @@ -446,7 +446,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. @@ -494,8 +494,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_not_existing, previously_destroyed, }) } @@ -567,7 +567,7 @@ impl JournaledState { &mut self, address: Address, db: &mut DB, - ) -> Result<(bool, bool), EVMError> { + ) -> Result> { let is_spurious_dragon_enabled = SpecId::enabled(self.spec, SPURIOUS_DRAGON); let (acc, is_cold) = self.load_account(address, db)?; @@ -578,7 +578,11 @@ impl JournaledState { let is_touched = acc.is_touched(); is_existing || is_touched }; - Ok((is_cold, exist)) + + Ok(LoadAccountResult { + is_not_existing: !exist, + is_cold, + }) } /// Loads code. From fab521a016133c263f4f64b33239730d9ee1b555 Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 7 Mar 2024 23:48:27 +0100 Subject: [PATCH 22/54] refactor eofcreate a little --- crates/interpreter/src/instruction_result.rs | 6 ++-- .../interpreter/src/instructions/contract.rs | 4 +-- crates/interpreter/src/interpreter.rs | 5 ++-- crates/revm/src/context.rs | 30 +++++++++++-------- crates/revm/src/frame.rs | 4 +-- 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/crates/interpreter/src/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index de93d1cc38..1865e35b52 100644 --- a/crates/interpreter/src/instruction_result.rs +++ b/crates/interpreter/src/instruction_result.rs @@ -10,7 +10,7 @@ pub enum InstructionResult { Stop, Return, SelfDestruct, - EofCreate, + ReturnContract, // revert codes Revert = 0x10, // revert opcode @@ -110,7 +110,7 @@ macro_rules! return_ok { | InstructionResult::Stop | InstructionResult::Return | InstructionResult::SelfDestruct - | InstructionResult::EofCreate + | InstructionResult::ReturnContract }; } @@ -232,7 +232,7 @@ impl From for SuccessOrHalt { InstructionResult::SelfDestruct => Self::Success(SuccessReason::SelfDestruct), InstructionResult::Revert => Self::Revert, // TODO EOFCreate is not external opcode. - InstructionResult::EofCreate => Self::FatalExternalError, + InstructionResult::ReturnContract => Self::FatalExternalError, InstructionResult::CallOrCreate => Self::InternalCallOrCreate, // used only in interpreter loop InstructionResult::CallTooDeep => Self::Halt(HaltReason::CallTooDeep), // not gonna happen for first call InstructionResult::OutOfFunds => Self::Halt(HaltReason::OutOfFunds), // Check for first call is done separately. diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 3678e40a2f..084109ad2c 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -131,14 +131,14 @@ pub fn txcreate(interpreter: &mut Interpreter, _host: &mut H) { cost_per_word::(initcode.len() as u64) ); - // Create new address + // 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 and reimburse it after call ends. + // spend all gas. It will be reimbursed after frame returns. gas!(interpreter, gas_limit); interpreter.next_action = InterpreterAction::EOFCreate { diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 0d45eac94d..d22b0d16a1 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -265,16 +265,17 @@ impl Interpreter { // Save data to return data buffer if the create reverted create_outcome.output().to_owned() } else { - // Otherwise clear it + // Otherwise clear it. Note that RETURN opcode should abort. Bytes::new() }; match instruction_result { - InstructionResult::EofCreate => { + 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()); } + // TODO(EOF) check what do to with Depth call and out of fund errors. return_revert!() => { push!(self, U256::ZERO); self.gas.erase_cost(create_outcome.gas().remaining()); diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index 16e4879cbe..7ba8e9ba61 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -446,14 +446,11 @@ impl EvmContext { spec_id: SpecId, inputs: &EOFCreateInput, ) -> Result> { - // Prepare crate. - let gas = Gas::new(inputs.gas_limit); - let return_error = |e| { Ok(FrameOrResult::new_eofcreate_result( InterpreterResult { result: e, - gas, + gas: Gas::new(inputs.gas_limit), output: Bytes::new(), }, inputs.created_address, @@ -462,6 +459,7 @@ impl EvmContext { }; // Check depth + // TODO(EOF) what to do on system error is still discussed. if self.journaled_state.depth() > CALL_STACK_LIMIT { return return_error(InstructionResult::CallTooDeep); } @@ -476,6 +474,7 @@ impl EvmContext { // 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); } @@ -498,6 +497,7 @@ impl EvmContext { let contract = Box::new(Contract::new( Bytes::new(), + // fine to clone as it is Bytes. Bytecode::Eof(inputs.eof_init_code.clone()), None, inputs.created_address, @@ -505,8 +505,8 @@ impl EvmContext { inputs.value, )); - let mut interpreter = Interpreter::new(contract, gas.limit(), false); - // EOF init will enabled RETURNCONTRACT opcode. + 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( @@ -629,24 +629,28 @@ impl EvmContext { address: Address, journal_checkpoint: JournalCheckpoint, ) { - if interpreter_result.result != InstructionResult::EofCreate { + // 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; } - // Note that we still execute Return opcode and return the bytes. - // In EOF those opcodes should abort execution. - // For Return that returns bytes is okay as gas is still protecting us from ddos - // and if it fails on oog, behaviour will be same as if it failed on return. // commit changes reduces depth by -1. self.journaled_state.checkpoint_commit(); + // decode bytecode is fast operation. let bytecode = Eof::decode(interpreter_result.output.clone()).expect("Eof is already verified"); + + // TODO(EOF) should we do keccak256 over bytes? self.journaled_state .set_code(address, Bytecode::Eof(bytecode)); - - interpreter_result.result = InstructionResult::Return; } /// Handles create return. diff --git a/crates/revm/src/frame.rs b/crates/revm/src/frame.rs index f050d841e9..b24bab3f23 100644 --- a/crates/revm/src/frame.rs +++ b/crates/revm/src/frame.rs @@ -75,8 +75,8 @@ impl FrameResult { FrameResult::Create(outcome) => { Output::Create(outcome.result.output.clone(), outcome.address) } - FrameResult::EOFCreate(outcome) => { - panic!("EOFCreateOutcome does not have output"); + FrameResult::EOFCreate(_) => { + panic!("EOFCreate can't be called from external world."); } } } From e5abe46cf86fc0382fea80ca53de5488c288c26f Mon Sep 17 00:00:00 2001 From: rakita Date: Fri, 8 Mar 2024 01:23:06 +0100 Subject: [PATCH 23/54] some work on extcall --- .../interpreter/src/instructions/contract.rs | 93 +++++++++++++----- .../src/instructions/contract/call_helpers.rs | 94 +++++++++---------- .../src/interpreter/shared_memory.rs | 18 +++- 3 files changed, 130 insertions(+), 75 deletions(-) diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 084109ad2c..a487451303 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -1,6 +1,8 @@ mod call_helpers; -pub use call_helpers::{calc_call_gas, get_memory_input_and_out_ranges}; +pub use call_helpers::{ + calc_call_gas, get_memory_input_and_out_ranges, resize_memory_and_return_range, +}; use revm_primitives::keccak256; use crate::{ @@ -162,30 +164,45 @@ pub fn extcall(interpreter: &mut Interpreter, host: &mut H) error_on_disabled_eof!(interpreter); panic_on_eof!(interpreter); pop_address!(interpreter, to); - pop!(interpreter, value); + pop!(interpreter, input_offset, input_size, value); if interpreter.is_static && value != U256::ZERO { interpreter.instruction_result = InstructionResult::CallNotAllowedInsideStatic; return; } - // TODO(EOF) check if destination is EOF. - let Some((input, return_memory_offset)) = get_memory_input_and_out_ranges(interpreter) else { + let Some(return_memory_offset) = + resize_memory_and_return_range(interpreter, input_offset, input_size) + else { return; }; - let Some(mut gas_limit) = calc_call_gas::( - interpreter, - host, - to, - value != U256::ZERO, - u64::MAX, - true, - true, - ) else { + // TODO(EOF) check if destination is EOF. + let Some(load_result) = host.load_account(to) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; + // TODO(EOF) is EOF! + if load_result.is_cold { + //gas!(interpreter, gas::COLD_ACCOUNT_ACCESS); + return; + } + + let is_new = !load_result.is_not_existing; + let call_cost = + gas::call_cost::(value != U256::ZERO, is_new, load_result.is_cold, true, true); + gas!(interpreter, call_cost); - let mut gas_limit = max(gas_limit, 5000); + // 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; + } gas!(interpreter, gas_limit); // Call host to interact with target contract @@ -308,10 +325,14 @@ pub fn call(interpreter: &mut Interpreter, host: &mut H) { return; }; + let Some(load_result) = host.load_account(to) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + let Some(mut gas_limit) = calc_call_gas::( interpreter, - host, - to, + load_result, value != U256::ZERO, local_gas_limit, true, @@ -364,10 +385,14 @@ pub fn call_code(interpreter: &mut Interpreter, host: &mut return; }; + let Some(load_result) = host.load_account(to) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + let Some(mut gas_limit) = calc_call_gas::( interpreter, - host, - to, + load_result, value != U256::ZERO, local_gas_limit, true, @@ -420,9 +445,19 @@ pub fn delegate_call(interpreter: &mut Interpreter, host: & return; }; - let Some(gas_limit) = - calc_call_gas::(interpreter, host, to, false, local_gas_limit, false, false) - else { + let Some(load_result) = host.load_account(to) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + + let Some(gas_limit) = calc_call_gas::( + interpreter, + load_result, + false, + local_gas_limit, + false, + false, + ) else { return; }; @@ -468,9 +503,19 @@ pub fn static_call(interpreter: &mut Interpreter, host: &mu return; }; - let Some(gas_limit) = - calc_call_gas::(interpreter, host, to, false, local_gas_limit, false, true) - else { + let Some(load_result) = host.load_account(to) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + + let Some(gas_limit) = calc_call_gas::( + interpreter, + load_result, + false, + local_gas_limit, + false, + true, + ) else { return; }; gas!(interpreter, gas_limit); diff --git a/crates/interpreter/src/instructions/contract/call_helpers.rs b/crates/interpreter/src/instructions/contract/call_helpers.rs index e3f178f166..4036c83ba6 100644 --- a/crates/interpreter/src/instructions/contract/call_helpers.rs +++ b/crates/interpreter/src/instructions/contract/call_helpers.rs @@ -1,8 +1,10 @@ +use revm_primitives::U256; + use crate::{ - gas::{self}, + gas, interpreter::Interpreter, - primitives::{Address, Bytes, Spec, SpecId::*}, - Host, InstructionResult, + primitives::{Bytes, Spec, SpecId::*}, + Host, InstructionResult, LoadAccountResult, }; use core::{cmp::min, ops::Range}; @@ -12,66 +14,64 @@ pub fn get_memory_input_and_out_ranges( ) -> 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); - shared_memory_resize!(interpreter, in_offset, in_len, None); - Bytes::copy_from_slice(interpreter.shared_memory.slice(in_offset, in_len)) - } else { - Bytes::new() - }; + 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)) +} - 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); - shared_memory_resize!(interpreter, out_offset, out_len, None); - out_offset +/// 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); + shared_memory_resize!(interpreter, offset, len, None); + offset } else { usize::MAX //unrealistic value so we are sure it is not used }; - - Some((input, out_offset..out_offset + out_len)) + Some(offset..offset + len) } #[inline] pub fn calc_call_gas( interpreter: &mut Interpreter, - host: &mut H, - to: Address, + load_result: LoadAccountResult, has_transfer: bool, local_gas_limit: u64, is_call_or_callcode: bool, is_call_or_staticcall: bool, ) -> Option { - let Some(load_result) = host.load_account(to) else { - interpreter.instruction_result = InstructionResult::FatalExternalError; - return None; - }; let is_new = !load_result.is_not_existing; + let call_cost = gas::call_cost::( + has_transfer, + is_new, + load_result.is_cold, + is_call_or_callcode, + is_call_or_staticcall, + ); - if interpreter.is_eof { - // TODO(EOF) - None - } else { - let call_cost = gas::call_cost::( - has_transfer, - is_new, - load_result.is_cold, - is_call_or_callcode, - is_call_or_staticcall, - ); - - gas!(interpreter, call_cost, None); + 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 - }; + // 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) - } + Some(gas_limit) } diff --git a/crates/interpreter/src/interpreter/shared_memory.rs b/crates/interpreter/src/interpreter/shared_memory.rs index 1d88e0e4d9..1fea3f5769 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() + ) }) } From 4aa166a5ef010a9bae4c3321449e2cc097ac73e7 Mon Sep 17 00:00:00 2001 From: rakita Date: Fri, 15 Mar 2024 20:32:38 +0100 Subject: [PATCH 24/54] feat: refactor simplify CallInput, eof extcalls --- bins/revme/src/cmd/statetest/runner.rs | 6 +- crates/interpreter/src/call_inputs.rs | 97 +++---- crates/interpreter/src/create_inputs.rs | 4 +- crates/interpreter/src/gas/calc.rs | 52 +--- .../interpreter/src/instructions/contract.rs | 273 ++++++++++-------- .../src/instructions/contract/call_helpers.rs | 10 +- crates/interpreter/src/instructions/host.rs | 14 +- crates/interpreter/src/instructions/macros.rs | 15 +- crates/interpreter/src/instructions/opcode.rs | 2 +- crates/interpreter/src/instructions/system.rs | 4 +- .../interpreter/src/interpreter/contract.rs | 30 +- crates/interpreter/src/lib.rs | 2 +- crates/primitives/src/env.rs | 13 +- crates/revm/src/context/evm_context.rs | 66 +++-- crates/revm/src/context/inner_evm_context.rs | 8 +- crates/revm/src/evm.rs | 2 +- crates/revm/src/inspector/customprinter.rs | 9 +- 17 files changed, 299 insertions(+), 308 deletions(-) diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index 3c75f38e04..e9b0e75956 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; @@ -401,7 +400,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); } @@ -421,6 +420,7 @@ pub fn execute_test_suite( let mut evm = Evm::builder() .with_spec_id(spec_id) .with_db(state) + .with_env(env.clone()) .with_external_context(TracerEip3155::new(Box::new(stdout()), false)) .append_handler_register(inspector_handle_register) .build(); diff --git a/crates/interpreter/src/call_inputs.rs b/crates/interpreter/src/call_inputs.rs index 0d9063be57..83a309baa3 100644 --- a/crates/interpreter/src/call_inputs.rs +++ b/crates/interpreter/src/call_inputs.rs @@ -6,46 +6,52 @@ use std::boxed::Box; #[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 return memory offset where the output of the call is written. + /// For EOF this range is invalid as EOF does not return anything. + pub return_memory_offset: Range, /// The gas limit of the call. pub gas_limit: u64, - /// The context of the call. - pub context: CallContext, + /// This account bytecode 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 this call. + pub caller: Address, + /// Ether value that is transferred. + /// + /// If enum is `Value` ether transfer is executed + /// between `caller`` and the `target_address`. + /// + /// If enum is `ApparentValue` transfer is not done and apparent value is + /// used by CALLVALUE opcode. This is needed for delegate call. + pub value: TransferValue, + /// The scheme used for the call. + pub scheme: CallScheme, /// 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, + /// Is called from EOF code. + pub is_eof: bool, } 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 { + let TransactTo::Call(target_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, - }, + 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, }) } @@ -54,6 +60,12 @@ impl CallInputs { 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. @@ -70,42 +82,19 @@ pub enum CallScheme { StaticCall, } -/// Context of a runtime call. +/// Transfered value from caller to callee. #[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, +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 CallContext { +impl Default for TransferValue { fn default() -> Self { - CallContext { - address: Address::default(), - caller: Address::default(), - code_address: Address::default(), - apparent_value: U256::default(), - scheme: CallScheme::Call, - } + TransferValue::Value(U256::ZERO) } } - -/// 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, -} diff --git a/crates/interpreter/src/create_inputs.rs b/crates/interpreter/src/create_inputs.rs index 6119a1b272..6db951831a 100644 --- a/crates/interpreter/src/create_inputs.rs +++ b/crates/interpreter/src/create_inputs.rs @@ -21,13 +21,13 @@ pub struct CreateInputs { 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 { + let TransactTo::Create = tx_env.transact_to else { return None; }; Some(CreateInputs { caller: tx_env.caller, - scheme, + scheme: CreateScheme::Create, value: tx_env.value, init_code: tx_env.data.clone(), gas_limit, diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index 3ab0b3b119..f0a904f675 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -272,8 +272,9 @@ pub fn selfdestruct_cost(res: SelfDestructResult) -> u64 { } #[inline] -pub fn call_gas(is_cold: bool) -> u64 { - if SPEC::enabled(BERLIN) { +pub fn call_cost(transfers_value: bool, is_new: bool, is_cold: bool) -> u64 { + // Account access. + let mut gas = if SPEC::enabled(BERLIN) { if is_cold { COLD_ACCOUNT_ACCESS_COST } else { @@ -284,20 +285,20 @@ pub fn call_gas(is_cold: bool) -> u64 { 700 } else { 40 + }; + + // transfer value cost + if transfers_value { + gas += CALLVALUE; } -} -#[inline] -pub fn call_cost( - transfers_value: bool, - is_new: bool, - is_cold: bool, - is_call_or_callcode: bool, - is_call_or_staticcall: bool, -) -> u64 { - call_gas::(is_cold) - + xfer_cost(is_call_or_callcode, transfers_value) - + new_cost::(is_call_or_staticcall, is_new, transfers_value) + // new account cost; + // EIP-161: State trie clearing (invariant-preserving alternative) + if is_new || (SPEC::enabled(SPURIOUS_DRAGON) && transfers_value) { + gas += NEWACCOUNT; + } + + gas } #[inline] @@ -313,29 +314,6 @@ pub fn warm_cold_cost(is_cold: bool, regular_value: u64) -> u64 { } } -#[inline] -fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 { - if is_call_or_callcode && transfers_value { - CALLVALUE - } else { - 0 - } -} - -#[inline] -fn new_cost(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 { - return 0; - } - - NEWACCOUNT -} - #[inline] pub fn memory_gas(a: usize) -> u64 { let a = a as u64; diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index e3412471e4..40c610b9df 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -3,14 +3,14 @@ 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; +use revm_primitives::{keccak256, BerlinSpec}; use crate::{ gas::{self, cost_per_word, BASE, EOF_CREATE_GAS, KECCAK256WORD}, interpreter::{Interpreter, InterpreterAction}, primitives::{Address, Bytes, Eof, Spec, SpecId::*, B256, U256}, - CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, EOFCreateInput, Host, - InstructionResult, Transfer, MAX_INITCODE_SIZE, + CallInputs, CallScheme, CreateInputs, CreateScheme, EOFCreateInput, Host, InstructionResult, + TransferValue, MAX_INITCODE_SIZE, }; use core::{cmp::max, ops::Range}; use std::boxed::Box; @@ -77,7 +77,7 @@ pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) { // Send container for execution container is preverified. interpreter.next_action = InterpreterAction::EOFCreate { inputs: Box::new(EOFCreateInput::new( - interpreter.contract.address, + interpreter.contract.target_address, created_address, value, eof, @@ -145,7 +145,7 @@ pub fn txcreate(interpreter: &mut Interpreter, _host: &mut H) { interpreter.next_action = InterpreterAction::EOFCreate { inputs: Box::new(EOFCreateInput::new( - interpreter.contract.address, + interpreter.contract.target_address, created_address, value, eof, @@ -160,37 +160,37 @@ pub fn return_contract(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); } -pub fn extcall(interpreter: &mut Interpreter, host: &mut H) { - error_on_disabled_eof!(interpreter); - panic_on_eof!(interpreter); - pop_address!(interpreter, to); - pop!(interpreter, input_offset, input_size, value); - if interpreter.is_static && value != U256::ZERO { - interpreter.instruction_result = InstructionResult::CallNotAllowedInsideStatic; - return; - } +pub fn extcall_input(interpreter: &mut Interpreter) -> Option { + pop_ret!(interpreter, input_offset, input_size, None); - let Some(return_memory_offset) = - resize_memory_and_return_range(interpreter, input_offset, input_size) - else { - return; - }; + let return_memory_offset = + resize_memory_and_return_range(interpreter, input_offset, input_size)?; - // TODO(EOF) check if destination is EOF. - let Some(load_result) = host.load_account(to) else { + 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; + return None; }; - // TODO(EOF) is EOF! + if load_result.is_cold { - //gas!(interpreter, gas::COLD_ACCOUNT_ACCESS); - return; + gas!(interpreter, gas::COLD_ACCOUNT_ACCESS_COST, None); } let is_new = !load_result.is_not_existing; - let call_cost = - gas::call_cost::(value != U256::ZERO, is_new, load_result.is_cold, true, true); - gas!(interpreter, call_cost); + let call_cost = gas::call_cost::(transfers_value, is_new, load_result.is_cold); + 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). @@ -201,43 +201,115 @@ pub fn extcall(interpreter: &mut Interpreter, host: &mut H) interpreter.instruction_result = InstructionResult::CallNotAllowedInsideStatic; // TODO(EOF) error; // interpreter.instruction_result = InstructionResult::CallGasTooLow; - return; + return None; } - gas!(interpreter, gas_limit); - let input = Bytes::new(); + // 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); + panic_on_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 { - 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, - }, + target_address: target_address, + caller: interpreter.contract.target_address, + bytecode_address: target_address, + value: TransferValue::Value(value), + scheme: CallScheme::Call, is_static: interpreter.is_static, - return_memory_offset, + is_eof: true, + return_memory_offset: 0..0, }), }; interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn extdcall(interpreter: &mut Interpreter, host: &mut H) { +pub fn extdcall(interpreter: &mut Interpreter, host: &mut H) { error_on_disabled_eof!(interpreter); + panic_on_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: 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); + panic_on_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: 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( @@ -300,7 +372,7 @@ pub fn create( // Call host to interact with target contract interpreter.next_action = InterpreterAction::Create { inputs: Box::new(CreateInputs { - caller: interpreter.contract.address, + caller: interpreter.contract.target_address, scheme, value, init_code: code, @@ -337,8 +409,6 @@ pub fn call(interpreter: &mut Interpreter, host: &mut H) { load_result, value != U256::ZERO, local_gas_limit, - true, - true, ) else { return; }; @@ -353,22 +423,15 @@ pub fn call(interpreter: &mut Interpreter, host: &mut H) { // 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, - }, + 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, }), }; @@ -397,8 +460,6 @@ pub fn call_code(interpreter: &mut Interpreter, host: &mut load_result, value != U256::ZERO, local_gas_limit, - true, - false, ) else { return; }; @@ -413,22 +474,15 @@ pub fn call_code(interpreter: &mut Interpreter, host: &mut // 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, - }, + target_address: interpreter.contract.target_address, + caller: interpreter.contract.target_address, + bytecode_address: to, + value: TransferValue::ApparentValue(value), + scheme: CallScheme::CallCode, is_static: interpreter.is_static, + is_eof: false, return_memory_offset, }), }; @@ -452,14 +506,9 @@ pub fn delegate_call(interpreter: &mut Interpreter, host: & return; }; - let Some(gas_limit) = calc_call_gas::( - interpreter, - load_result, - false, - local_gas_limit, - false, - false, - ) else { + let Some(gas_limit) = + calc_call_gas::(interpreter, load_result, false, local_gas_limit) + else { return; }; @@ -468,24 +517,15 @@ pub fn delegate_call(interpreter: &mut Interpreter, host: & // 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, - }, + 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, }), }; @@ -500,7 +540,6 @@ pub fn static_call(interpreter: &mut Interpreter, host: &mu // 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; }; @@ -510,14 +549,9 @@ pub fn static_call(interpreter: &mut Interpreter, host: &mu return; }; - let Some(gas_limit) = calc_call_gas::( - interpreter, - load_result, - false, - local_gas_limit, - false, - true, - ) else { + let Some(gas_limit) = + calc_call_gas::(interpreter, load_result, false, local_gas_limit) + else { return; }; gas!(interpreter, gas_limit); @@ -525,24 +559,15 @@ pub fn static_call(interpreter: &mut Interpreter, host: &mu // 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, - }, + 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, }), }; diff --git a/crates/interpreter/src/instructions/contract/call_helpers.rs b/crates/interpreter/src/instructions/contract/call_helpers.rs index 4036c83ba6..bd726af32d 100644 --- a/crates/interpreter/src/instructions/contract/call_helpers.rs +++ b/crates/interpreter/src/instructions/contract/call_helpers.rs @@ -50,17 +50,9 @@ pub fn calc_call_gas( load_result: LoadAccountResult, has_transfer: bool, local_gas_limit: u64, - is_call_or_callcode: bool, - is_call_or_staticcall: bool, ) -> Option { let is_new = !load_result.is_not_existing; - let call_cost = gas::call_cost::( - has_transfer, - is_new, - load_result.is_cold, - is_call_or_callcode, - is_call_or_staticcall, - ); + let call_cost = gas::call_cost::(has_transfer, is_new, load_result.is_cold); gas!(interpreter, call_cost, None); diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index aa3f6a3f01..28b8d818d9 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -32,7 +32,7 @@ pub fn balance(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 { + let Some((balance, _)) = host.balance(interpreter.contract.target_address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; @@ -140,7 +140,7 @@ pub fn blockhash(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 { + let Some((value, is_cold)) = host.sload(interpreter.contract.target_address, index) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; @@ -157,7 +157,7 @@ pub fn sstore(interpreter: &mut Interpreter, host: &mut H) 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,7 +178,7 @@ pub fn tstore(interpreter: &mut Interpreter, host: &mut H) pop!(interpreter, index, value); - host.tstore(interpreter.contract.address, index, value); + host.tstore(interpreter.contract.target_address, index, value); } /// EIP-1153: Transient storage opcodes @@ -189,7 +189,7 @@ pub fn tload(interpreter: &mut Interpreter, host: &mut H) { 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) { @@ -218,7 +218,7 @@ pub fn log(interpreter: &mut Interpreter, host: &mut H) } let log = Log { - address: interpreter.contract.address, + address: interpreter.contract.target_address, data: LogData::new(topics, data).expect("LogData should have <=4 topics"), }; @@ -230,7 +230,7 @@ pub fn selfdestruct(interpreter: &mut Interpreter, host: &m 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; }; diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index 2c41b68938..e4654e0a41 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -94,17 +94,26 @@ macro_rules! shared_memory_resize { 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, ()) + }; +} + +macro_rules! pop_address_ret { + ($interp:expr, $x1:ident, $ret:expr) => { if $interp.stack.len() < 1 { $interp.instruction_result = InstructionResult::StackUnderflow; - return; + return $ret; } // SAFETY: Length is checked above. let $x1 = Address::from_word(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 = InstructionResult::StackUnderflow; - return; + return $ret; } // SAFETY: Length is checked above. let $x1 = Address::from_word(B256::from(unsafe { $interp.stack.pop_unsafe() })); diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index 2717eed212..e1b1b40c6d 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -391,7 +391,7 @@ opcodes! { // 0xF6 0xF7 => RETURNDATALOAD => system::returndataload::, 0xF8 => EXTCALL => contract::extcall::, - 0xF9 => EXFCALL => contract::extdcall::, + 0xF9 => EXFCALL => contract::extdcall::, 0xFA => STATICCALL => contract::static_call::, 0xFB => EXTSCALL => contract::extscall::, // 0xFC diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index 3f9acf8dca..5a63efcc06 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) { @@ -79,7 +79,7 @@ pub fn calldatasize(interpreter: &mut Interpreter, _host: &mut H) { 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) { diff --git a/crates/interpreter/src/interpreter/contract.rs b/crates/interpreter/src/interpreter/contract.rs index 6a88507a5f..94620f01b8 100644 --- a/crates/interpreter/src/interpreter/contract.rs +++ b/crates/interpreter/src/interpreter/contract.rs @@ -1,6 +1,8 @@ use super::analysis::to_analysed; -use crate::primitives::{Address, Bytecode, Bytes, Env, TransactTo, B256, U256}; -use crate::CallContext; +use crate::{ + primitives::{Address, Bytecode, Bytes, Env, TransactTo, B256, U256}, + CallInputs, +}; /// EVM contract information. #[derive(Clone, Debug, Default)] @@ -12,12 +14,12 @@ pub struct Contract { pub bytecode: Bytecode, /// Bytecode hash for legacy. For EOF this would be None. pub hash: Option, - /// Contract address - pub address: Address, + /// 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 { @@ -27,9 +29,9 @@ impl Contract { input: Bytes, bytecode: Bytecode, hash: Option, - address: Address, + target_address: Address, caller: Address, - value: U256, + call_value: U256, ) -> Self { let bytecode = to_analysed(bytecode).try_into().expect("it is analyzed"); @@ -37,9 +39,9 @@ impl Contract { input, bytecode, hash, - address, + target_address, caller, - value, + call_value, } } @@ -48,7 +50,7 @@ impl Contract { 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(), @@ -66,15 +68,15 @@ impl Contract { input: Bytes, bytecode: Bytecode, hash: Option, - call_context: &CallContext, + 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(), ) } diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index c589bc1f83..7cba88c094 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -26,7 +26,7 @@ pub mod instructions; mod interpreter; // Reexport primary types. -pub use call_inputs::{CallContext, CallInputs, CallScheme, Transfer}; +pub use call_inputs::{CallInputs, CallScheme, TransferValue}; pub use call_outcome::CallOutcome; pub use create_inputs::{CreateInputs, CreateScheme}; pub use create_outcome::CreateOutcome; diff --git a/crates/primitives/src/env.rs b/crates/primitives/src/env.rs index 5ddbe4a62b..8bbda8e927 100644 --- a/crates/primitives/src/env.rs +++ b/crates/primitives/src/env.rs @@ -662,7 +662,7 @@ pub enum TransactTo { /// Simple call to an address. Call(Address), /// Contract creation. - Create(CreateScheme), + Create, } impl TransactTo { @@ -675,15 +675,8 @@ impl TransactTo { /// Creates a contract. #[inline] pub fn create() -> Self { - Self::Create(CreateScheme::Create) + Self::Create } - - /// Creates a contract with the given salt using `CREATE2`. - #[inline] - pub fn create2(salt: U256) -> Self { - Self::Create(CreateScheme::Create2 { salt }) - } - /// Returns `true` if the transaction is `Call`. #[inline] pub fn is_call(&self) -> bool { @@ -693,7 +686,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) } } diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index 19709df975..3b9f212f18 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 { @@ -202,7 +209,7 @@ impl EvmContext { inputs.input.clone(), bytecode, Some(code_hash), - &inputs.context, + &inputs, )); // Create interpreter and executes call and push new CallStackFrame. Ok(FrameOrResult::new_call_frame( @@ -220,6 +227,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 +244,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 +354,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 7b92e99ee8..736c1d76ab 100644 --- a/crates/revm/src/context/inner_evm_context.rs +++ b/crates/revm/src/context/inner_evm_context.rs @@ -1,18 +1,18 @@ use crate::{ db::Database, interpreter::{ - analysis::to_analysed, gas, return_ok, CallInputs, Contract, CreateInputs, EOFCreateInput, - Gas, InstructionResult, Interpreter, InterpreterResult, LoadAccountResult, SStoreResult, + 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, - Eof, HandlerCfg, HashSet, Spec, + Eof, HashSet, Spec, SpecId::{self, *}, B256, U256, }, - ContextPrecompiles, FrameOrResult, JournalCheckpoint, CALL_STACK_LIMIT, + FrameOrResult, JournalCheckpoint, CALL_STACK_LIMIT, }; use std::boxed::Box; diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index b9537f590c..f2b24b50f0 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -363,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(), )?, diff --git a/crates/revm/src/inspector/customprinter.rs b/crates/revm/src/inspector/customprinter.rs index 5e8c948b2e..0a5ca22203 100644 --- a/crates/revm/src/inspector/customprinter.rs +++ b/crates/revm/src/inspector/customprinter.rs @@ -79,11 +79,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 From 449f243a874b126f130938c900bb814ddf381726 Mon Sep 17 00:00:00 2001 From: rakita Date: Mon, 18 Mar 2024 14:48:08 +0100 Subject: [PATCH 25/54] feat: restructure OpCode and add stack input/output num --- .../interpreter/src/instructions/contract.rs | 3 - .../interpreter/src/instructions/host_env.rs | 2 +- crates/interpreter/src/instructions/memory.rs | 6 +- crates/interpreter/src/instructions/opcode.rs | 1048 +++++------------ crates/interpreter/src/instructions/system.rs | 11 +- .../interpreter/src/interpreter/analysis.rs | 79 +- 6 files changed, 414 insertions(+), 735 deletions(-) diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 40c610b9df..84dc68bfb6 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -212,7 +212,6 @@ pub fn extcall_gas_calc( pub fn extcall(interpreter: &mut Interpreter, host: &mut H) { error_on_disabled_eof!(interpreter); - panic_on_eof!(interpreter); pop_address!(interpreter, target_address); // input call @@ -248,7 +247,6 @@ pub fn extcall(interpreter: &mut Interpreter, host: &mut H) pub fn extdcall(interpreter: &mut Interpreter, host: &mut H) { error_on_disabled_eof!(interpreter); - panic_on_eof!(interpreter); pop_address!(interpreter, target_address); // input call @@ -282,7 +280,6 @@ pub fn extdcall(interpreter: &mut Interpreter, host: &mut H pub fn extscall(interpreter: &mut Interpreter, host: &mut H) { error_on_disabled_eof!(interpreter); - panic_on_eof!(interpreter); pop_address!(interpreter, target_address); // input call diff --git a/crates/interpreter/src/instructions/host_env.rs b/crates/interpreter/src/instructions/host_env.rs index cce993bac6..08a5d10b19 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/memory.rs b/crates/interpreter/src/instructions/memory.rs index 6a63eb6b03..4c385eba15 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!(interpreter, index); - let index = as_usize_or_fail!(interpreter, index); + pop_top!(interpreter, item); + let index = as_usize_or_fail!(interpreter, item); shared_memory_resize!(interpreter, index, 32); - push!(interpreter, interpreter.shared_memory.get_u256(index)); + *item = interpreter.shared_memory.get_u256(index); } pub fn mstore(interpreter: &mut Interpreter, _host: &mut H) { diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index e1b1b40c6d..e9429e8c26 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -92,10 +92,112 @@ where 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_JUMPMAP`] 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_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, + } + } + + /// 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. + pub const fn is_jumpdest_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. + pub const fn is_jump_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. + pub fn is_push_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 { + 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 + } +} + pub const NOP: u8 = JUMPDEST; macro_rules! opcodes { - ($($val:literal => $name:ident => $f:expr),* $(,)?) => { + ($($val:literal => $name:ident => $f:expr => ($inputs:literal,$outputs:literal)),* $(,)?) => { // Constants for each opcode. This also takes care of duplicate names. $( #[doc = concat!("The `", stringify!($val), "` (\"", stringify!($name),"\") opcode.")] @@ -106,6 +208,42 @@ macro_rules! opcodes { pub const $name: Self = Self($val); )*} + impl OpCode { + + /// Returns inputs for the given opcode. + pub const fn inputs(&self) -> u8 { + match self.0 { + $($val => $inputs,)* + _ => 0, + } + } + + /// Returns outputs for the given opcode. + pub const fn outputs(&self) -> u8 { + match self.0 { + $($val => $outputs,)* + _ => 0, + } + } + + /// Returns a difference between input and output. + pub const fn diff(&self) -> i8 { + match self.0 { + $($val => $outputs as i8 - $inputs as i8,)* + _ => 0, + } + } + + /// 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) { + match self.0 { + $($val => ($inputs,$outputs),)* + _ => (0,0), + } + } + } + /// Maps each opcode to its name. pub const OPCODE_JUMPMAP: [Option<&'static str>; 256] = { let mut map = [None; 256]; @@ -136,40 +274,40 @@ macro_rules! opcodes { // 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, + 0x00 => STOP => control::stop => (0,0), + + 0x01 => ADD => arithmetic::wrapping_add => (2,1), + 0x02 => MUL => arithmetic::wrapping_mul => (2,1), + 0x03 => SUB => arithmetic::wrapping_sub => (2,1), + 0x04 => DIV => arithmetic::div => (2,1), + 0x05 => SDIV => arithmetic::sdiv => (2,1), + 0x06 => MOD => arithmetic::rem => (2,1), + 0x07 => SMOD => arithmetic::smod => (2,1), + 0x08 => ADDMOD => arithmetic::addmod => (3,1), + 0x09 => MULMOD => arithmetic::mulmod => (3,1), + 0x0A => EXP => arithmetic::exp:: => (2,1), + 0x0B => SIGNEXTEND => arithmetic::signextend => (2,1), // 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::, + 0x10 => LT => bitwise::lt => (2,1), + 0x11 => GT => bitwise::gt => (2,1), + 0x12 => SLT => bitwise::slt => (2,1), + 0x13 => SGT => bitwise::sgt => (2,1), + 0x14 => EQ => bitwise::eq => (2,1), + 0x15 => ISZERO => bitwise::iszero => (1,1), + 0x16 => AND => bitwise::bitand => (2,1), + 0x17 => OR => bitwise::bitor => (2,1), + 0x18 => XOR => bitwise::bitxor => (2,1), + 0x19 => NOT => bitwise::not => (1,1), + 0x1A => BYTE => bitwise::byte => (2,1), + 0x1B => SHL => bitwise::shl:: => (2,1), + 0x1C => SHR => bitwise::shr:: => (2,1), + 0x1D => SAR => bitwise::sar:: => (2,1), // 0x1E // 0x1F - 0x20 => KECCAK256 => system::keccak256, + 0x20 => KECCAK256 => system::keccak256 => (2,1), // 0x21 // 0x22 // 0x23 @@ -185,128 +323,128 @@ opcodes! { // 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::, + 0x30 => ADDRESS => system::address => (0,1), + 0x31 => BALANCE => host::balance:: => (1,1), + 0x32 => ORIGIN => host_env::origin => (0,1), + 0x33 => CALLER => system::caller => (0,1), + 0x34 => CALLVALUE => system::callvalue => (0,1), + 0x35 => CALLDATALOAD => system::calldataload => (1,1), + 0x36 => CALLDATASIZE => system::calldatasize => (0,1), + 0x37 => CALLDATACOPY => system::calldatacopy => (0,1), + 0x38 => CODESIZE => system::codesize => (0,1), + 0x39 => CODECOPY => system::codecopy => (3,0), + + 0x3A => GASPRICE => host_env::gasprice => (0,1), + 0x3B => EXTCODESIZE => host::extcodesize:: => (1,1), + 0x3C => EXTCODECOPY => host::extcodecopy:: => (4,0), + 0x3D => RETURNDATASIZE => system::returndatasize:: => (0,1), + 0x3E => RETURNDATACOPY => system::returndatacopy:: => (3,0), + 0x3F => EXTCODEHASH => host::extcodehash:: => (1,1), + 0x40 => BLOCKHASH => host::blockhash => (1,1), + 0x41 => COINBASE => host_env::coinbase => (0,1), + 0x42 => TIMESTAMP => host_env::timestamp => (0,1), + 0x43 => NUMBER => host_env::block_number => (0,1), + 0x44 => DIFFICULTY => host_env::difficulty:: => (0,1), + 0x45 => GASLIMIT => host_env::gaslimit => (0,1), + 0x46 => CHAINID => host_env::chainid:: => (0,1), + 0x47 => SELFBALANCE => host::selfbalance:: => (0,1), + 0x48 => BASEFEE => host_env::basefee:: => (0,1), + 0x49 => BLOBHASH => host_env::blob_hash:: => (1,1), + 0x4A => BLOBBASEFEE => host_env::blob_basefee:: => (0,1), // 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_or_nop, - 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>, + 0x50 => POP => stack::pop => (1,0), + 0x51 => MLOAD => memory::mload => (1,1), + 0x52 => MSTORE => memory::mstore => (2,0), + 0x53 => MSTORE8 => memory::mstore8 => (2,0), + 0x54 => SLOAD => host::sload:: => (1,1), + 0x55 => SSTORE => host::sstore:: => (2,0), + 0x56 => JUMP => control::jump => (1,0), + 0x57 => JUMPI => control::jumpi => (2,0), + 0x58 => PC => control::pc => (0,1), + 0x59 => MSIZE => memory::msize => (0,1), + 0x5A => GAS => system::gas => (0,1), + 0x5B => JUMPDEST => control::jumpdest_or_nop => (0,0), + 0x5C => TLOAD => host::tload:: => (1,1), + 0x5D => TSTORE => host::tstore:: => (2,0), + 0x5E => MCOPY => memory::mcopy:: => (3,0), + + 0x5F => PUSH0 => stack::push0:: => (0,1), + 0x60 => PUSH1 => stack::push::<1, H> => (0,1), + 0x61 => PUSH2 => stack::push::<2, H> => (0,1), + 0x62 => PUSH3 => stack::push::<3, H> => (0,1), + 0x63 => PUSH4 => stack::push::<4, H> => (0,1), + 0x64 => PUSH5 => stack::push::<5, H> => (0,1), + 0x65 => PUSH6 => stack::push::<6, H> => (0,1), + 0x66 => PUSH7 => stack::push::<7, H> => (0,1), + 0x67 => PUSH8 => stack::push::<8, H> => (0,1), + 0x68 => PUSH9 => stack::push::<9, H> => (0,1), + 0x69 => PUSH10 => stack::push::<10, H> => (0,1), + 0x6A => PUSH11 => stack::push::<11, H> => (0,1), + 0x6B => PUSH12 => stack::push::<12, H> => (0,1), + 0x6C => PUSH13 => stack::push::<13, H> => (0,1), + 0x6D => PUSH14 => stack::push::<14, H> => (0,1), + 0x6E => PUSH15 => stack::push::<15, H> => (0,1), + 0x6F => PUSH16 => stack::push::<16, H> => (0,1), + 0x70 => PUSH17 => stack::push::<17, H> => (0,1), + 0x71 => PUSH18 => stack::push::<18, H> => (0,1), + 0x72 => PUSH19 => stack::push::<19, H> => (0,1), + 0x73 => PUSH20 => stack::push::<20, H> => (0,1), + 0x74 => PUSH21 => stack::push::<21, H> => (0,1), + 0x75 => PUSH22 => stack::push::<22, H> => (0,1), + 0x76 => PUSH23 => stack::push::<23, H> => (0,1), + 0x77 => PUSH24 => stack::push::<24, H> => (0,1), + 0x78 => PUSH25 => stack::push::<25, H> => (0,1), + 0x79 => PUSH26 => stack::push::<26, H> => (0,1), + 0x7A => PUSH27 => stack::push::<27, H> => (0,1), + 0x7B => PUSH28 => stack::push::<28, H> => (0,1), + 0x7C => PUSH29 => stack::push::<29, H> => (0,1), + 0x7D => PUSH30 => stack::push::<30, H> => (0,1), + 0x7E => PUSH31 => stack::push::<31, H> => (0,1), + 0x7F => PUSH32 => stack::push::<32, H> => (0,1), + + 0x80 => DUP1 => stack::dup::<1, H> => (0,1), + 0x81 => DUP2 => stack::dup::<2, H> => (0,1), + 0x82 => DUP3 => stack::dup::<3, H> => (0,1), + 0x83 => DUP4 => stack::dup::<4, H> => (0,1), + 0x84 => DUP5 => stack::dup::<5, H> => (0,1), + 0x85 => DUP6 => stack::dup::<6, H> => (0,1), + 0x86 => DUP7 => stack::dup::<7, H> => (0,1), + 0x87 => DUP8 => stack::dup::<8, H> => (0,1), + 0x88 => DUP9 => stack::dup::<9, H> => (0,1), + 0x89 => DUP10 => stack::dup::<10, H> => (0,1), + 0x8A => DUP11 => stack::dup::<11, H> => (0,1), + 0x8B => DUP12 => stack::dup::<12, H> => (0,1), + 0x8C => DUP13 => stack::dup::<13, H> => (0,1), + 0x8D => DUP14 => stack::dup::<14, H> => (0,1), + 0x8E => DUP15 => stack::dup::<15, H> => (0,1), + 0x8F => DUP16 => stack::dup::<16, H> => (0,1), + + 0x90 => SWAP1 => stack::swap::<1, H> => (0,0), + 0x91 => SWAP2 => stack::swap::<2, H> => (0,0), + 0x92 => SWAP3 => stack::swap::<3, H> => (0,0), + 0x93 => SWAP4 => stack::swap::<4, H> => (0,0), + 0x94 => SWAP5 => stack::swap::<5, H> => (0,0), + 0x95 => SWAP6 => stack::swap::<6, H> => (0,0), + 0x96 => SWAP7 => stack::swap::<7, H> => (0,0), + 0x97 => SWAP8 => stack::swap::<8, H> => (0,0), + 0x98 => SWAP9 => stack::swap::<9, H> => (0,0), + 0x99 => SWAP10 => stack::swap::<10, H> => (0,0), + 0x9A => SWAP11 => stack::swap::<11, H> => (0,0), + 0x9B => SWAP12 => stack::swap::<12, H> => (0,0), + 0x9C => SWAP13 => stack::swap::<13, H> => (0,0), + 0x9D => SWAP14 => stack::swap::<14, H> => (0,0), + 0x9E => SWAP15 => stack::swap::<15, H> => (0,0), + 0x9F => SWAP16 => stack::swap::<16, H> => (0,0), + + 0xA0 => LOG0 => host::log::<0, H> => (2,0), + 0xA1 => LOG1 => host::log::<1, H> => (3,0), + 0xA2 => LOG2 => host::log::<2, H> => (4,0), + 0xA3 => LOG3 => host::log::<3, H> => (5,0), + 0xA4 => LOG4 => host::log::<4, H> => (6,0), // 0xA5 // 0xA6 // 0xA7 @@ -350,10 +488,10 @@ opcodes! { // 0xCD // 0xCE // 0xCF - 0xD0 => DATALOAD => data::data_load, - 0xD1 => DATALOADN => data::data_loadn, - 0xD2 => DATASIZE => data::data_size, - 0xD3 => DATACOPY => data::data_copy, + 0xD0 => DATALOAD => data::data_load => (1,1), + 0xD1 => DATALOADN => data::data_loadn => (0,1), + 0xD2 => DATASIZE => data::data_size => (0,1), + 0xD3 => DATACOPY => data::data_copy => (3,0), // 0xD4 // 0xD5 // 0xD6 @@ -366,585 +504,51 @@ opcodes! { // 0xDD // 0xDE // 0xDF - 0xE0 => RJUMP => control::rjump, - 0xE1 => RJUMPI => control::rjumpi, - 0xE2 => RJUMPV => control::rjumpv, - 0xE3 => CALLF => control::callf, - 0xE4 => RETF => control::retf, - 0xE5 => JUMPF => control::jumpf, - 0xE6 => DUPN => stack::dupn, - 0xE7 => SWAPN => stack::swapn, - 0xE8 => EXCHANGE => stack::exchange, + 0xE0 => RJUMP => control::rjump => (0,0), + 0xE1 => RJUMPI => control::rjumpi => (1,0), + 0xE2 => RJUMPV => control::rjumpv => (1,0), + 0xE3 => CALLF => control::callf => (0,0), + 0xE4 => RETF => control::retf => (0,0), + 0xE5 => JUMPF => control::jumpf => (0,0), + 0xE6 => DUPN => stack::dupn => (0,0), + 0xE7 => SWAPN => stack::swapn => (0,0), + 0xE8 => EXCHANGE => stack::exchange => (0,0), // 0xE9 // 0xEA // 0xEB - 0xEC => EOFCREATE => contract::eofcreate::, - 0xED => CREATE4 => contract::txcreate::, - 0xEE => RETURNCONTRACT => contract::return_contract::, + 0xEC => EOFCREATE => contract::eofcreate:: => (4,1), + 0xED => CREATE4 => contract::txcreate:: => (5,1), + 0xEE => RETURNCONTRACT => contract::return_contract:: => (0,0), // TODO(EOF) input/output // 0xEF - 0xF0 => CREATE => contract::create::, - 0xF1 => CALL => contract::call::, - 0xF2 => CALLCODE => contract::call_code::, - 0xF3 => RETURN => control::ret, - 0xF4 => DELEGATECALL => contract::delegate_call::, - 0xF5 => CREATE2 => contract::create::, + 0xF0 => CREATE => contract::create:: => (0,0), + 0xF1 => CALL => contract::call:: => (0,0), + 0xF2 => CALLCODE => contract::call_code:: => (0,0), + 0xF3 => RETURN => control::ret => (0,0), + 0xF4 => DELEGATECALL => contract::delegate_call:: => (0,0), + 0xF5 => CREATE2 => contract::create:: => (0,0), // 0xF6 - 0xF7 => RETURNDATALOAD => system::returndataload::, - 0xF8 => EXTCALL => contract::extcall::, - 0xF9 => EXFCALL => contract::extdcall::, - 0xFA => STATICCALL => contract::static_call::, - 0xFB => EXTSCALL => contract::extscall::, + 0xF7 => RETURNDATALOAD => system::returndataload:: => (0,0), + 0xF8 => EXTCALL => contract::extcall:: => (0,0), + 0xF9 => EXFCALL => contract::extdcall:: => (0,0), + 0xFA => STATICCALL => contract::static_call:: => (0,0), + 0xFB => EXTSCALL => contract::extscall:: => (0,0), // 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, 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_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 - } - - #[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)] -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 - } + 0xFD => REVERT => control::revert:: => (0,0), + 0xFE => INVALID => control::invalid => (0,0), + 0xFF => SELFDESTRUCT => host::selfdestruct:: => (0,0), } -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), +#[cfg(test)] +mod tests { + use super::*; + + /// Test opcode. + pub fn test_opcode() { + let opcode = OpCode::new(0x00).unwrap(); + assert_eq!(opcode.is_jumpdest(), true); + assert_eq!(opcode.is_jump(), false); + assert_eq!(opcode.is_push(), false); + assert_eq!(opcode.as_str(), "STOP"); + assert_eq!(opcode.get(), 0x00); } } - -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, - PRAGUE, - LATEST, - ) -} diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index 5a63efcc06..70e58576d2 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -58,12 +58,13 @@ 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); + pop!(interpreter, offset); + let offset = as_usize_saturated!(offset); + let load = if offset < interpreter.contract.input.len() { + let have_bytes = 32.min(interpreter.contract.input.len() - offset); let mut bytes = [0u8; 32]; - bytes[..have_bytes].copy_from_slice(&interpreter.contract.input[index..index + have_bytes]); + bytes[..have_bytes] + .copy_from_slice(&interpreter.contract.input[offset..offset + have_bytes]); B256::new(bytes) } else { B256::ZERO diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 70500ca2b6..898e18611a 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -1,4 +1,5 @@ -use revm_primitives::{Bytes, LegacyAnalyzedBytecode}; +use revm_primitives::eof::TypesSection; +use revm_primitives::{Bytes, Eof, LegacyAnalyzedBytecode}; use crate::opcode; use crate::primitives::{ @@ -58,3 +59,79 @@ fn analyze(code: &[u8]) -> JumpTable { JumpTable(Arc::new(jumps)) } + +/// Validate Eof structures. +/// +/// do perf test on: +/// max eof containers +/// max depth of containers. +/// bytecode iteration. +pub fn validate_eof(eof: &Eof) -> Result<(), ()> { + // clone is cheat as it is Bytes and a header. + let mut analyze_eof = vec![eof.clone()]; + + while let Some(eof) = analyze_eof.pop() { + // iterate over types and code + for (types, bytes) in eof + .body + .types_section + .iter() + .zip(eof.body.code_section.iter()) + { + types.validate()?; + } + + // iterate over containers, convert them to Eof and add to analyze_eof + for container in eof.body.container_section { + let container_eof = Eof::decode(container)?; + analyze_eof.push(container_eof); + } + } + + // Eof is valid + Ok(()) +} + + + +pub fn validate_eof_bytecode(code: &[u8], types: &TypesSection) -> Result<(), ()> { + let max_stack_size = types.inputs as u16; + let stack_size = types.inputs as u16; + + let mut iter = code.as_ptr(); + let end = code.as_ptr().wrapping_add(code.len()); + + let mut eof_table = [0; 256]; + + while iter < end { + let opcode = unsafe { *iter }; + let opcode_info = eof_table[opcode as usize] += 1; + + // if opcode::JUMPDEST == opcode { + // // SAFETY: jumps are max length of the code + // unsafe { jumps.set_unchecked(iterator.offset_from(start) as usize, true) } + // iterator = unsafe { iterator.offset(1) }; + // } else { + // let push_offset = opcode.wrapping_sub(opcode::PUSH1); + // if push_offset < 32 { + // // SAFETY: iterator access range is checked in the while loop + // iterator = unsafe { iterator.offset((push_offset + 2) as isize) }; + // } else { + // // SAFETY: iterator access range is checked in the while loop + // iterator = unsafe { iterator.offset(1) }; + // } + // } + } + + // iterate over opcodes + + if max_stack_size != types.max_stack_size { + return Err(()); + } + + if stack_size != types.outputs as u16 { + return Err(()); + } + + Ok(()) +} From 183adaf680607ebb8da04bc02dcab70c52ebf741 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 19 Mar 2024 01:12:55 +0100 Subject: [PATCH 26/54] add flags for stack_io and not_eof --- crates/interpreter/src/instructions.rs | 2 +- crates/interpreter/src/instructions/opcode.rs | 506 ++++++++++-------- .../interpreter/src/interpreter/analysis.rs | 6 +- crates/interpreter/src/lib.rs | 2 +- 4 files changed, 278 insertions(+), 238 deletions(-) diff --git a/crates/interpreter/src/instructions.rs b/crates/interpreter/src/instructions.rs index 634ec284cc..0de794092a 100644 --- a/crates/interpreter/src/instructions.rs +++ b/crates/interpreter/src/instructions.rs @@ -16,4 +16,4 @@ pub mod stack; pub mod system; pub mod utility; -pub use opcode::{Instruction, OpCode, OPCODE_JUMPMAP}; +pub use opcode::{Instruction, OpCode, OPCODE_INFO_JUMPTABLE}; diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index e9429e8c26..bad3b60722 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -1,11 +1,7 @@ //! EVM opcode definitions and utilities. use super::*; -use crate::{ - gas, - primitives::{Spec, SpecId}, - Host, Interpreter, -}; +use crate::{primitives::Spec, Host, Interpreter}; use core::fmt; use std::boxed::Box; @@ -95,7 +91,7 @@ where /// An EVM opcode. /// /// This is always a valid opcode, as declared in the [`opcode`][self] module or the -/// [`OPCODE_JUMPMAP`] constant. +/// [`OPCODE_INFO_JUMPTABLE`] constant. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct OpCode(u8); @@ -103,8 +99,8 @@ 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_JUMPMAP[n as usize] { - f.write_str(val) + if let Some(val) = OPCODE_INFO_JUMPTABLE[n as usize] { + f.write_str(val.name) } else { write!(f, "UNKNOWN(0x{n:02X})") } @@ -115,7 +111,7 @@ impl OpCode { /// Instantiate a new opcode from a u8. #[inline] pub const fn new(opcode: u8) -> Option { - match OPCODE_JUMPMAP[opcode as usize] { + match OPCODE_INFO_JUMPTABLE[opcode as usize] { Some(_) => Some(Self(opcode)), None => None, } @@ -128,7 +124,8 @@ impl OpCode { } /// Takes a u8 and returns true if it is a jump destination. - pub const fn is_jumpdest_op(opcode: u8) -> bool { + #[inline] + pub const fn is_jumpdest_by_op(opcode: u8) -> bool { if let Some(opcode) = Self::new(opcode) { opcode.is_jumpdest() } else { @@ -143,7 +140,8 @@ impl OpCode { } /// Takes a u8 and returns true if it is a jump instruction. - pub const fn is_jump_op(opcode: u8) -> bool { + #[inline] + pub const fn is_jump_by_op(opcode: u8) -> bool { if let Some(opcode) = Self::new(opcode) { opcode.is_jump() } else { @@ -158,7 +156,8 @@ impl OpCode { } /// Takes a u8 and returns true if it is a push instruction. - pub fn is_push_op(opcode: u8) -> bool { + #[inline] + pub fn is_push_by_op(opcode: u8) -> bool { if let Some(opcode) = Self::new(opcode) { opcode.is_push() } else { @@ -180,13 +179,48 @@ impl 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 + self.info().name + } + + /// 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 diff(&self) -> i8 { + self.info().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 { - "unknown" + 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 { @@ -194,10 +228,36 @@ impl OpCode { } } +/// 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, + pub is_eof: bool, + pub size: u8, +} + +impl OpCodeInfo { + pub const fn new(name: &'static str) -> Self { + Self { + name, + inputs: 0, + outputs: 0, + is_eof: true, + size: 1, + } + } + + pub const fn diff(&self) -> i8 { + self.inputs as i8 - self.outputs as i8 + } +} + pub const NOP: u8 = JUMPDEST; macro_rules! opcodes { - ($($val:literal => $name:ident => $f:expr => ($inputs:literal,$outputs:literal)),* $(,)?) => { + ($($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.")] @@ -208,51 +268,17 @@ macro_rules! opcodes { pub const $name: Self = Self($val); )*} - impl OpCode { - - /// Returns inputs for the given opcode. - pub const fn inputs(&self) -> u8 { - match self.0 { - $($val => $inputs,)* - _ => 0, - } - } - - /// Returns outputs for the given opcode. - pub const fn outputs(&self) -> u8 { - match self.0 { - $($val => $outputs,)* - _ => 0, - } - } - - /// Returns a difference between input and output. - pub const fn diff(&self) -> i8 { - match self.0 { - $($val => $outputs as i8 - $inputs as i8,)* - _ => 0, - } - } - - /// 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) { - match self.0 { - $($val => ($inputs,$outputs),)* - _ => (0,0), - } - } - } - /// Maps each opcode to its name. - pub const OPCODE_JUMPMAP: [Option<&'static str>; 256] = { + 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; - map[$val] = Some(stringify!($name)); + let opcode = OpCodeInfo::new(stringify!($name)); + $( let opcode = $modifier$(::< $( $modifier_num ),+ >)? (opcode);)* + map[$val] = Some(opcode); )* let _ = prev; map @@ -268,46 +294,62 @@ macro_rules! opcodes { }; } +pub const fn not_eof(mut opcode: OpCodeInfo) -> OpCodeInfo { + opcode.is_eof = true; + opcode +} + +pub const fn size(mut opcode: OpCodeInfo) -> OpCodeInfo { + opcode.size = N; + 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 => (0,0), - - 0x01 => ADD => arithmetic::wrapping_add => (2,1), - 0x02 => MUL => arithmetic::wrapping_mul => (2,1), - 0x03 => SUB => arithmetic::wrapping_sub => (2,1), - 0x04 => DIV => arithmetic::div => (2,1), - 0x05 => SDIV => arithmetic::sdiv => (2,1), - 0x06 => MOD => arithmetic::rem => (2,1), - 0x07 => SMOD => arithmetic::smod => (2,1), - 0x08 => ADDMOD => arithmetic::addmod => (3,1), - 0x09 => MULMOD => arithmetic::mulmod => (3,1), - 0x0A => EXP => arithmetic::exp:: => (2,1), - 0x0B => SIGNEXTEND => arithmetic::signextend => (2,1), + 0x00 => STOP => control::stop => stack_io<0,0>; + + 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 => (2,1), - 0x11 => GT => bitwise::gt => (2,1), - 0x12 => SLT => bitwise::slt => (2,1), - 0x13 => SGT => bitwise::sgt => (2,1), - 0x14 => EQ => bitwise::eq => (2,1), - 0x15 => ISZERO => bitwise::iszero => (1,1), - 0x16 => AND => bitwise::bitand => (2,1), - 0x17 => OR => bitwise::bitor => (2,1), - 0x18 => XOR => bitwise::bitxor => (2,1), - 0x19 => NOT => bitwise::not => (1,1), - 0x1A => BYTE => bitwise::byte => (2,1), - 0x1B => SHL => bitwise::shl:: => (2,1), - 0x1C => SHR => bitwise::shr:: => (2,1), - 0x1D => SAR => bitwise::sar:: => (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 => (2,1), + 0x20 => KECCAK256 => system::keccak256 => stack_io<2, 1>; // 0x21 // 0x22 // 0x23 @@ -323,128 +365,128 @@ opcodes! { // 0x2D // 0x2E // 0x2F - 0x30 => ADDRESS => system::address => (0,1), - 0x31 => BALANCE => host::balance:: => (1,1), - 0x32 => ORIGIN => host_env::origin => (0,1), - 0x33 => CALLER => system::caller => (0,1), - 0x34 => CALLVALUE => system::callvalue => (0,1), - 0x35 => CALLDATALOAD => system::calldataload => (1,1), - 0x36 => CALLDATASIZE => system::calldatasize => (0,1), - 0x37 => CALLDATACOPY => system::calldatacopy => (0,1), - 0x38 => CODESIZE => system::codesize => (0,1), - 0x39 => CODECOPY => system::codecopy => (3,0), - - 0x3A => GASPRICE => host_env::gasprice => (0,1), - 0x3B => EXTCODESIZE => host::extcodesize:: => (1,1), - 0x3C => EXTCODECOPY => host::extcodecopy:: => (4,0), - 0x3D => RETURNDATASIZE => system::returndatasize:: => (0,1), - 0x3E => RETURNDATACOPY => system::returndatacopy:: => (3,0), - 0x3F => EXTCODEHASH => host::extcodehash:: => (1,1), - 0x40 => BLOCKHASH => host::blockhash => (1,1), - 0x41 => COINBASE => host_env::coinbase => (0,1), - 0x42 => TIMESTAMP => host_env::timestamp => (0,1), - 0x43 => NUMBER => host_env::block_number => (0,1), - 0x44 => DIFFICULTY => host_env::difficulty:: => (0,1), - 0x45 => GASLIMIT => host_env::gaslimit => (0,1), - 0x46 => CHAINID => host_env::chainid:: => (0,1), - 0x47 => SELFBALANCE => host::selfbalance:: => (0,1), - 0x48 => BASEFEE => host_env::basefee:: => (0,1), - 0x49 => BLOBHASH => host_env::blob_hash:: => (1,1), - 0x4A => BLOBBASEFEE => host_env::blob_basefee:: => (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<0, 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 => (1,0), - 0x51 => MLOAD => memory::mload => (1,1), - 0x52 => MSTORE => memory::mstore => (2,0), - 0x53 => MSTORE8 => memory::mstore8 => (2,0), - 0x54 => SLOAD => host::sload:: => (1,1), - 0x55 => SSTORE => host::sstore:: => (2,0), - 0x56 => JUMP => control::jump => (1,0), - 0x57 => JUMPI => control::jumpi => (2,0), - 0x58 => PC => control::pc => (0,1), - 0x59 => MSIZE => memory::msize => (0,1), - 0x5A => GAS => system::gas => (0,1), - 0x5B => JUMPDEST => control::jumpdest_or_nop => (0,0), - 0x5C => TLOAD => host::tload:: => (1,1), - 0x5D => TSTORE => host::tstore:: => (2,0), - 0x5E => MCOPY => memory::mcopy:: => (3,0), - - 0x5F => PUSH0 => stack::push0:: => (0,1), - 0x60 => PUSH1 => stack::push::<1, H> => (0,1), - 0x61 => PUSH2 => stack::push::<2, H> => (0,1), - 0x62 => PUSH3 => stack::push::<3, H> => (0,1), - 0x63 => PUSH4 => stack::push::<4, H> => (0,1), - 0x64 => PUSH5 => stack::push::<5, H> => (0,1), - 0x65 => PUSH6 => stack::push::<6, H> => (0,1), - 0x66 => PUSH7 => stack::push::<7, H> => (0,1), - 0x67 => PUSH8 => stack::push::<8, H> => (0,1), - 0x68 => PUSH9 => stack::push::<9, H> => (0,1), - 0x69 => PUSH10 => stack::push::<10, H> => (0,1), - 0x6A => PUSH11 => stack::push::<11, H> => (0,1), - 0x6B => PUSH12 => stack::push::<12, H> => (0,1), - 0x6C => PUSH13 => stack::push::<13, H> => (0,1), - 0x6D => PUSH14 => stack::push::<14, H> => (0,1), - 0x6E => PUSH15 => stack::push::<15, H> => (0,1), - 0x6F => PUSH16 => stack::push::<16, H> => (0,1), - 0x70 => PUSH17 => stack::push::<17, H> => (0,1), - 0x71 => PUSH18 => stack::push::<18, H> => (0,1), - 0x72 => PUSH19 => stack::push::<19, H> => (0,1), - 0x73 => PUSH20 => stack::push::<20, H> => (0,1), - 0x74 => PUSH21 => stack::push::<21, H> => (0,1), - 0x75 => PUSH22 => stack::push::<22, H> => (0,1), - 0x76 => PUSH23 => stack::push::<23, H> => (0,1), - 0x77 => PUSH24 => stack::push::<24, H> => (0,1), - 0x78 => PUSH25 => stack::push::<25, H> => (0,1), - 0x79 => PUSH26 => stack::push::<26, H> => (0,1), - 0x7A => PUSH27 => stack::push::<27, H> => (0,1), - 0x7B => PUSH28 => stack::push::<28, H> => (0,1), - 0x7C => PUSH29 => stack::push::<29, H> => (0,1), - 0x7D => PUSH30 => stack::push::<30, H> => (0,1), - 0x7E => PUSH31 => stack::push::<31, H> => (0,1), - 0x7F => PUSH32 => stack::push::<32, H> => (0,1), - - 0x80 => DUP1 => stack::dup::<1, H> => (0,1), - 0x81 => DUP2 => stack::dup::<2, H> => (0,1), - 0x82 => DUP3 => stack::dup::<3, H> => (0,1), - 0x83 => DUP4 => stack::dup::<4, H> => (0,1), - 0x84 => DUP5 => stack::dup::<5, H> => (0,1), - 0x85 => DUP6 => stack::dup::<6, H> => (0,1), - 0x86 => DUP7 => stack::dup::<7, H> => (0,1), - 0x87 => DUP8 => stack::dup::<8, H> => (0,1), - 0x88 => DUP9 => stack::dup::<9, H> => (0,1), - 0x89 => DUP10 => stack::dup::<10, H> => (0,1), - 0x8A => DUP11 => stack::dup::<11, H> => (0,1), - 0x8B => DUP12 => stack::dup::<12, H> => (0,1), - 0x8C => DUP13 => stack::dup::<13, H> => (0,1), - 0x8D => DUP14 => stack::dup::<14, H> => (0,1), - 0x8E => DUP15 => stack::dup::<15, H> => (0,1), - 0x8F => DUP16 => stack::dup::<16, H> => (0,1), - - 0x90 => SWAP1 => stack::swap::<1, H> => (0,0), - 0x91 => SWAP2 => stack::swap::<2, H> => (0,0), - 0x92 => SWAP3 => stack::swap::<3, H> => (0,0), - 0x93 => SWAP4 => stack::swap::<4, H> => (0,0), - 0x94 => SWAP5 => stack::swap::<5, H> => (0,0), - 0x95 => SWAP6 => stack::swap::<6, H> => (0,0), - 0x96 => SWAP7 => stack::swap::<7, H> => (0,0), - 0x97 => SWAP8 => stack::swap::<8, H> => (0,0), - 0x98 => SWAP9 => stack::swap::<9, H> => (0,0), - 0x99 => SWAP10 => stack::swap::<10, H> => (0,0), - 0x9A => SWAP11 => stack::swap::<11, H> => (0,0), - 0x9B => SWAP12 => stack::swap::<12, H> => (0,0), - 0x9C => SWAP13 => stack::swap::<13, H> => (0,0), - 0x9D => SWAP14 => stack::swap::<14, H> => (0,0), - 0x9E => SWAP15 => stack::swap::<15, H> => (0,0), - 0x9F => SWAP16 => stack::swap::<16, H> => (0,0), - - 0xA0 => LOG0 => host::log::<0, H> => (2,0), - 0xA1 => LOG1 => host::log::<1, H> => (3,0), - 0xA2 => LOG2 => host::log::<2, H> => (4,0), - 0xA3 => LOG3 => host::log::<3, H> => (5,0), - 0xA4 => LOG4 => host::log::<4, H> => (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>; + 0x57 => JUMPI => control::jumpi => stack_io<2, 0>; + 0x58 => PC => control::pc => stack_io<0, 1>; + 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>, size<2>; + 0x61 => PUSH2 => stack::push::<2, H> => stack_io<0, 1>, size<3>; + 0x62 => PUSH3 => stack::push::<3, H> => stack_io<0, 1>, size<4>; + 0x63 => PUSH4 => stack::push::<4, H> => stack_io<0, 1>, size<5>; + 0x64 => PUSH5 => stack::push::<5, H> => stack_io<0, 1>, size<6>; + 0x65 => PUSH6 => stack::push::<6, H> => stack_io<0, 1>, size<7>; + 0x66 => PUSH7 => stack::push::<7, H> => stack_io<0, 1>, size<8>; + 0x67 => PUSH8 => stack::push::<8, H> => stack_io<0, 1>, size<9>; + 0x68 => PUSH9 => stack::push::<9, H> => stack_io<0, 1>, size<10>; + 0x69 => PUSH10 => stack::push::<10, H> => stack_io<0, 1>, size<11>; + 0x6A => PUSH11 => stack::push::<11, H> => stack_io<0, 1>, size<12>; + 0x6B => PUSH12 => stack::push::<12, H> => stack_io<0, 1>, size<13>; + 0x6C => PUSH13 => stack::push::<13, H> => stack_io<0, 1>, size<14>; + 0x6D => PUSH14 => stack::push::<14, H> => stack_io<0, 1>, size<15>; + 0x6E => PUSH15 => stack::push::<15, H> => stack_io<0, 1>, size<16>; + 0x6F => PUSH16 => stack::push::<16, H> => stack_io<0, 1>, size<17>; + 0x70 => PUSH17 => stack::push::<17, H> => stack_io<0, 1>, size<18>; + 0x71 => PUSH18 => stack::push::<18, H> => stack_io<0, 1>, size<19>; + 0x72 => PUSH19 => stack::push::<19, H> => stack_io<0, 1>, size<20>; + 0x73 => PUSH20 => stack::push::<20, H> => stack_io<0, 1>, size<21>; + 0x74 => PUSH21 => stack::push::<21, H> => stack_io<0, 1>, size<22>; + 0x75 => PUSH22 => stack::push::<22, H> => stack_io<0, 1>, size<23>; + 0x76 => PUSH23 => stack::push::<23, H> => stack_io<0, 1>, size<24>; + 0x77 => PUSH24 => stack::push::<24, H> => stack_io<0, 1>, size<25>; + 0x78 => PUSH25 => stack::push::<25, H> => stack_io<0, 1>, size<26>; + 0x79 => PUSH26 => stack::push::<26, H> => stack_io<0, 1>, size<27>; + 0x7A => PUSH27 => stack::push::<27, H> => stack_io<0, 1>, size<28>; + 0x7B => PUSH28 => stack::push::<28, H> => stack_io<0, 1>, size<29>; + 0x7C => PUSH29 => stack::push::<29, H> => stack_io<0, 1>, size<30>; + 0x7D => PUSH30 => stack::push::<30, H> => stack_io<0, 1>, size<31>; + 0x7E => PUSH31 => stack::push::<31, H> => stack_io<0, 1>, size<32>; + 0x7F => PUSH32 => stack::push::<32, H> => stack_io<0, 1>, size<33>; + + 0x80 => DUP1 => stack::dup::<1, H> => stack_io<0, 1>; + 0x81 => DUP2 => stack::dup::<2, H> => stack_io<0, 1>; + 0x82 => DUP3 => stack::dup::<3, H> => stack_io<0, 1>; + 0x83 => DUP4 => stack::dup::<4, H> => stack_io<0, 1>; + 0x84 => DUP5 => stack::dup::<5, H> => stack_io<0, 1>; + 0x85 => DUP6 => stack::dup::<6, H> => stack_io<0, 1>; + 0x86 => DUP7 => stack::dup::<7, H> => stack_io<0, 1>; + 0x87 => DUP8 => stack::dup::<8, H> => stack_io<0, 1>; + 0x88 => DUP9 => stack::dup::<9, H> => stack_io<0, 1>; + 0x89 => DUP10 => stack::dup::<10, H> => stack_io<0, 1>; + 0x8A => DUP11 => stack::dup::<11, H> => stack_io<0, 1>; + 0x8B => DUP12 => stack::dup::<12, H> => stack_io<0, 1>; + 0x8C => DUP13 => stack::dup::<13, H> => stack_io<0, 1>; + 0x8D => DUP14 => stack::dup::<14, H> => stack_io<0, 1>; + 0x8E => DUP15 => stack::dup::<15, H> => stack_io<0, 1>; + 0x8F => DUP16 => stack::dup::<16, H> => stack_io<0, 1>; + + 0x90 => SWAP1 => stack::swap::<1, H> => stack_io<0, 0>; + 0x91 => SWAP2 => stack::swap::<2, H> => stack_io<0, 0>; + 0x92 => SWAP3 => stack::swap::<3, H> => stack_io<0, 0>; + 0x93 => SWAP4 => stack::swap::<4, H> => stack_io<0, 0>; + 0x94 => SWAP5 => stack::swap::<5, H> => stack_io<0, 0>; + 0x95 => SWAP6 => stack::swap::<6, H> => stack_io<0, 0>; + 0x96 => SWAP7 => stack::swap::<7, H> => stack_io<0, 0>; + 0x97 => SWAP8 => stack::swap::<8, H> => stack_io<0, 0>; + 0x98 => SWAP9 => stack::swap::<9, H> => stack_io<0, 0>; + 0x99 => SWAP10 => stack::swap::<10, H> => stack_io<0, 0>; + 0x9A => SWAP11 => stack::swap::<11, H> => stack_io<0, 0>; + 0x9B => SWAP12 => stack::swap::<12, H> => stack_io<0, 0>; + 0x9C => SWAP13 => stack::swap::<13, H> => stack_io<0, 0>; + 0x9D => SWAP14 => stack::swap::<14, H> => stack_io<0, 0>; + 0x9E => SWAP15 => stack::swap::<15, H> => stack_io<0, 0>; + 0x9F => SWAP16 => stack::swap::<16, H> => stack_io<0, 0>; + + 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 @@ -488,10 +530,10 @@ opcodes! { // 0xCD // 0xCE // 0xCF - 0xD0 => DATALOAD => data::data_load => (1,1), - 0xD1 => DATALOADN => data::data_loadn => (0,1), - 0xD2 => DATASIZE => data::data_size => (0,1), - 0xD3 => DATACOPY => data::data_copy => (3,0), + 0xD0 => DATALOAD => data::data_load => stack_io<1, 1>; + 0xD1 => DATALOADN => data::data_loadn => stack_io<0, 1>; + 0xD2 => DATASIZE => data::data_size => stack_io<0, 1>; + 0xD3 => DATACOPY => data::data_copy => stack_io<3, 0>; // 0xD4 // 0xD5 // 0xD6 @@ -504,48 +546,48 @@ opcodes! { // 0xDD // 0xDE // 0xDF - 0xE0 => RJUMP => control::rjump => (0,0), - 0xE1 => RJUMPI => control::rjumpi => (1,0), - 0xE2 => RJUMPV => control::rjumpv => (1,0), - 0xE3 => CALLF => control::callf => (0,0), - 0xE4 => RETF => control::retf => (0,0), - 0xE5 => JUMPF => control::jumpf => (0,0), - 0xE6 => DUPN => stack::dupn => (0,0), - 0xE7 => SWAPN => stack::swapn => (0,0), - 0xE8 => EXCHANGE => stack::exchange => (0,0), + 0xE0 => RJUMP => control::rjump => stack_io<0, 0>; + 0xE1 => RJUMPI => control::rjumpi => stack_io<1, 0>; + 0xE2 => RJUMPV => control::rjumpv => stack_io<1, 0>; + 0xE3 => CALLF => control::callf => stack_io<0, 0>; + 0xE4 => RETF => control::retf => stack_io<0, 0>; + 0xE5 => JUMPF => control::jumpf => stack_io<0, 0>; + 0xE6 => DUPN => stack::dupn => stack_io<0, 0>; + 0xE7 => SWAPN => stack::swapn => stack_io<0, 0>; + 0xE8 => EXCHANGE => stack::exchange => stack_io<0, 0>; // 0xE9 // 0xEA // 0xEB - 0xEC => EOFCREATE => contract::eofcreate:: => (4,1), - 0xED => CREATE4 => contract::txcreate:: => (5,1), - 0xEE => RETURNCONTRACT => contract::return_contract:: => (0,0), // TODO(EOF) input/output + 0xEC => EOFCREATE => contract::eofcreate:: => stack_io<4, 1>; + 0xED => CREATE4 => contract::txcreate:: => stack_io<5, 1>; + 0xEE => RETURNCONTRACT => contract::return_contract:: => stack_io<0, 0>; // TODO(EOF) input/output // 0xEF - 0xF0 => CREATE => contract::create:: => (0,0), - 0xF1 => CALL => contract::call:: => (0,0), - 0xF2 => CALLCODE => contract::call_code:: => (0,0), - 0xF3 => RETURN => control::ret => (0,0), - 0xF4 => DELEGATECALL => contract::delegate_call:: => (0,0), - 0xF5 => CREATE2 => contract::create:: => (0,0), + 0xF0 => CREATE => contract::create:: => stack_io<4, 1>; + 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<0, 0>; + 0xF4 => DELEGATECALL => contract::delegate_call:: => stack_io<6, 1>, not_eof; + 0xF5 => CREATE2 => contract::create:: => stack_io<5, 1>; // 0xF6 - 0xF7 => RETURNDATALOAD => system::returndataload:: => (0,0), - 0xF8 => EXTCALL => contract::extcall:: => (0,0), - 0xF9 => EXFCALL => contract::extdcall:: => (0,0), - 0xFA => STATICCALL => contract::static_call:: => (0,0), - 0xFB => EXTSCALL => contract::extscall:: => (0,0), + 0xF7 => RETURNDATALOAD => system::returndataload:: => stack_io<0, 0>; // TODO(EOF) impl + 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:: => (0,0), - 0xFE => INVALID => control::invalid => (0,0), - 0xFF => SELFDESTRUCT => host::selfdestruct:: => (0,0), + 0xFD => REVERT => control::revert:: => stack_io<0, 0>; + 0xFE => INVALID => control::invalid => stack_io<0, 0>; + 0xFF => SELFDESTRUCT => host::selfdestruct:: => stack_io<1, 0>, not_eof; } #[cfg(test)] mod tests { use super::*; - /// Test opcode. - pub fn test_opcode() { + #[test] + fn test_opcode() { let opcode = OpCode::new(0x00).unwrap(); - assert_eq!(opcode.is_jumpdest(), true); + assert_eq!(opcode.is_jumpdest(), false); assert_eq!(opcode.is_jump(), false); assert_eq!(opcode.is_push(), false); assert_eq!(opcode.as_str(), "STOP"); diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 898e18611a..8f9785fb41 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -1,12 +1,12 @@ use revm_primitives::eof::TypesSection; use revm_primitives::{Bytes, Eof, LegacyAnalyzedBytecode}; -use crate::opcode; use crate::primitives::{ bitvec::prelude::{bitvec, BitVec, Lsb0}, legacy::JumpTable, Bytecode, }; +use crate::{opcode, OPCODE_INFO_JUMPTABLE}; use std::sync::Arc; /// Perform bytecode analysis. @@ -92,8 +92,6 @@ pub fn validate_eof(eof: &Eof) -> Result<(), ()> { Ok(()) } - - pub fn validate_eof_bytecode(code: &[u8], types: &TypesSection) -> Result<(), ()> { let max_stack_size = types.inputs as u16; let stack_size = types.inputs as u16; @@ -105,7 +103,7 @@ pub fn validate_eof_bytecode(code: &[u8], types: &TypesSection) -> Result<(), () while iter < end { let opcode = unsafe { *iter }; - let opcode_info = eof_table[opcode as usize] += 1; + let opcode_info = &OPCODE_INFO_JUMPTABLE[opcode as usize]; // if opcode::JUMPDEST == opcode { // // SAFETY: jumps are max length of the code diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index 7cba88c094..6cdbd425b1 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -36,7 +36,7 @@ pub use function_stack::{FunctionReturnFrame, FunctionStack}; pub use gas::Gas; pub use host::{DummyHost, Host, LoadAccountResult, SStoreResult, SelfDestructResult}; pub use instruction_result::*; -pub use instructions::{opcode, Instruction, OpCode, OPCODE_JUMPMAP}; +pub use instructions::{opcode, Instruction, OpCode, OPCODE_INFO_JUMPTABLE}; pub use interpreter::{ analysis, next_multiple_of_32, Contract, Interpreter, InterpreterAction, InterpreterResult, SharedMemory, Stack, EMPTY_SHARED_MEMORY, STACK_LIMIT, From 07c721a4e9c4387d84caa10cdf4c834ce512380c Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 19 Mar 2024 23:35:26 +0100 Subject: [PATCH 27/54] wip eof verification --- crates/interpreter/src/instructions/opcode.rs | 116 +++++++++++++++--- .../interpreter/src/interpreter/analysis.rs | 64 +++++++++- 2 files changed, 158 insertions(+), 22 deletions(-) diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index bad3b60722..fe191bf30f 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -234,7 +234,10 @@ 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, pub size: u8, } @@ -245,6 +248,7 @@ impl OpCodeInfo { inputs: 0, outputs: 0, is_eof: true, + is_terminating_opcode: false, size: 1, } } @@ -295,7 +299,7 @@ macro_rules! opcodes { } pub const fn not_eof(mut opcode: OpCodeInfo) -> OpCodeInfo { - opcode.is_eof = true; + opcode.is_eof = false; opcode } @@ -304,6 +308,11 @@ pub const fn size(mut opcode: OpCodeInfo) -> OpCodeInfo { 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; @@ -316,7 +325,7 @@ pub const fn stack_io(mut opcode: OpCodeInfo) -> OpCod // 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>; + 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>; @@ -404,8 +413,8 @@ opcodes! { 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>; - 0x57 => JUMPI => control::jumpi => 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>; 0x59 => MSIZE => memory::msize => stack_io<0, 1>; 0x5A => GAS => system::gas => stack_io<0, 1>, not_eof; @@ -531,7 +540,7 @@ opcodes! { // 0xCE // 0xCF 0xD0 => DATALOAD => data::data_load => stack_io<1, 1>; - 0xD1 => DATALOADN => data::data_loadn => stack_io<0, 1>; + 0xD1 => DATALOADN => data::data_loadn => stack_io<0, 1>, size<3>; 0xD2 => DATASIZE => data::data_size => stack_io<0, 1>; 0xD3 => DATACOPY => data::data_copy => stack_io<3, 0>; // 0xD4 @@ -546,26 +555,26 @@ opcodes! { // 0xDD // 0xDE // 0xDF - 0xE0 => RJUMP => control::rjump => stack_io<0, 0>; - 0xE1 => RJUMPI => control::rjumpi => stack_io<1, 0>; - 0xE2 => RJUMPV => control::rjumpv => stack_io<1, 0>; - 0xE3 => CALLF => control::callf => stack_io<0, 0>; - 0xE4 => RETF => control::retf => stack_io<0, 0>; - 0xE5 => JUMPF => control::jumpf => stack_io<0, 0>; - 0xE6 => DUPN => stack::dupn => stack_io<0, 0>; - 0xE7 => SWAPN => stack::swapn => stack_io<0, 0>; - 0xE8 => EXCHANGE => stack::exchange => stack_io<0, 0>; + 0xE0 => RJUMP => control::rjump => stack_io<0, 0>, size<3>; + 0xE1 => RJUMPI => control::rjumpi => stack_io<1, 0>, size<3>; + 0xE2 => RJUMPV => control::rjumpv => stack_io<1, 0>, size<3>; + 0xE3 => CALLF => control::callf => stack_io<0, 0>, size<3>; + 0xE4 => RETF => control::retf => stack_io<0, 0>, terminating; + 0xE5 => JUMPF => control::jumpf => stack_io<0, 0>, size<3>; + 0xE6 => DUPN => stack::dupn => stack_io<0, 0>, size<2>; + 0xE7 => SWAPN => stack::swapn => stack_io<0, 0>, size<2>; + 0xE8 => EXCHANGE => stack::exchange => stack_io<0, 0>, size<2>; // 0xE9 // 0xEA // 0xEB 0xEC => EOFCREATE => contract::eofcreate:: => stack_io<4, 1>; 0xED => CREATE4 => contract::txcreate:: => stack_io<5, 1>; - 0xEE => RETURNCONTRACT => contract::return_contract:: => stack_io<0, 0>; // TODO(EOF) input/output + 0xEE => RETURNCONTRACT => contract::return_contract:: => stack_io<0, 0>, terminating; // TODO(EOF) input/output // 0xEF 0xF0 => CREATE => contract::create:: => stack_io<4, 1>; 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<0, 0>; + 0xF3 => RETURN => control::ret => stack_io<0, 0>, terminating; 0xF4 => DELEGATECALL => contract::delegate_call:: => stack_io<6, 1>, not_eof; 0xF5 => CREATE2 => contract::create:: => stack_io<5, 1>; // 0xF6 @@ -575,9 +584,9 @@ opcodes! { 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<0, 0>; - 0xFE => INVALID => control::invalid => stack_io<0, 0>; - 0xFF => SELFDESTRUCT => host::selfdestruct:: => stack_io<1, 0>, not_eof; + 0xFD => REVERT => control::revert:: => stack_io<0, 0>, terminating; + 0xFE => INVALID => control::invalid => stack_io<0, 0>, not_eof, terminating; + 0xFF => SELFDESTRUCT => host::selfdestruct:: => stack_io<1, 0>, not_eof, terminating; } #[cfg(test)] @@ -593,4 +602,73 @@ mod tests { 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_eq!( + opcode.info().is_eof, + false, + "Opcode {:?} is not EOF", + opcode + ); + } + } + + #[test] + fn test_opcode_size() { + let mut opcodes = [0u8; 256]; + // PUSH opcodes + for push in PUSH1..PUSH32 { + opcodes[push as usize] = push - PUSH1 + 1; + } + opcodes[DATALOADN as usize] = 3; + opcodes[RJUMP as usize] = 3; + opcodes[RJUMPI as usize] = 3; + opcodes[RJUMPV as usize] = 3; + opcodes[CALLF as usize] = 3; + opcodes[JUMPF as usize] = 3; + opcodes[DUPN as usize] = 2; + opcodes[SWAPN as usize] = 2; + opcodes[EXCHANGE as usize] = 2; + } + + #[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, + 0x5f..=0x54, + 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] + pub fn test_terminating_opcodes() { + // TODO check JUMPF + let terminating = [RETF, JUMPF]; + } } diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 8f9785fb41..af55704075 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -99,11 +99,45 @@ pub fn validate_eof_bytecode(code: &[u8], types: &TypesSection) -> Result<(), () let mut iter = code.as_ptr(); let end = code.as_ptr().wrapping_add(code.len()); - let mut eof_table = [0; 256]; + let is_returning = false; + // all bytes that are intermediate. + let jumptable = vec![false; code.len()]; + + // We can check validity and jump destinations in one pass. while iter < end { - let opcode = unsafe { *iter }; - let opcode_info = &OPCODE_INFO_JUMPTABLE[opcode as usize]; + let op = unsafe { *iter }; + let opcode_info = &OPCODE_INFO_JUMPTABLE[op as usize]; + + // Unknown opcode + let Some(opcode) = opcode_info else { + return Err(()); + }; + + // check if the size of the opcode is within the bounds of the code + if unsafe { iter.add(opcode.size as usize - 1) } > end { + return Err(()); + } + + match op { + opcode::RJUMPV | opcode::RJUMP | opcode::RJUMPI => { + // check jump destination with bytecode size. + + // check if jump destination is valid + } + opcode::CALLF => { + // check codes size. + // targeted code needs to have zero outputs (be non returning). + } + opcode::RETF => { + // check if it is returning. TODO here + } + _ => {} + } + + // if let Some(jump) = opcode_info.jump { + // eof_table[jump as usize] += 1; + // } // if opcode::JUMPDEST == opcode { // // SAFETY: jumps are max length of the code @@ -133,3 +167,27 @@ pub fn validate_eof_bytecode(code: &[u8], types: &TypesSection) -> Result<(), () Ok(()) } + +/// Validate stack requirements and if all codes sections are used. +pub fn validate_stack_requirement(codes: &[u8]) -> Result<(), ()> { + #[derive(Copy, Clone)] + struct StackInfo { + min: u16, + max: u16, + } + let mut code_stack_access: Vec> = vec![None; codes.len()]; + let mut worklist: Vec = Vec::new(); + + while let Some(workitem) = worklist.pop() {} + + // Iterate over accessed code, error on not accessed opcode and return max stack requirement. + let mut max_stack_requirement = 0; + for opcode in code_stack_access { + if let Some(opcode) = opcode { + max_stack_requirement = core::cmp::max(opcode.max, max_stack_requirement); + } else { + return Err(()); + } + } + Ok(()) +} From 91d98c3dc5acc0adc0372d47d21ac9b9029d7e0b Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 21 Mar 2024 13:20:05 +0100 Subject: [PATCH 28/54] wip validation --- crates/interpreter/src/function_stack.rs | 1 + crates/interpreter/src/instructions/opcode.rs | 103 +++++---- .../interpreter/src/interpreter/analysis.rs | 209 ++++++++++++++++-- .../src/bytecode/eof/types_section.rs | 7 + 4 files changed, 251 insertions(+), 69 deletions(-) diff --git a/crates/interpreter/src/function_stack.rs b/crates/interpreter/src/function_stack.rs index e9cfe3f846..cf2690c913 100644 --- a/crates/interpreter/src/function_stack.rs +++ b/crates/interpreter/src/function_stack.rs @@ -1,3 +1,4 @@ +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/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index 596f1ba519..f40cde515d 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -238,8 +238,8 @@ impl OpCode { } /// Returns a difference between input and output. - pub const fn diff(&self) -> i8 { - self.info().diff() + pub const fn io_diff(&self) -> i16 { + self.info().io_diff() } pub const fn info_by_op(opcode: u8) -> Option { @@ -283,7 +283,11 @@ pub struct OpCodeInfo { pub is_eof: bool, // If the opcode is return from execution. aka STOP,RETURN, .. pub is_terminating_opcode: bool, - pub size: u8, + /// 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 { @@ -294,12 +298,12 @@ impl OpCodeInfo { outputs: 0, is_eof: true, is_terminating_opcode: false, - size: 1, + immediate_size: 0, } } - pub const fn diff(&self) -> i8 { - self.inputs as i8 - self.outputs as i8 + pub const fn io_diff(&self) -> i16 { + self.inputs as i16 - self.outputs as i16 } } @@ -348,8 +352,9 @@ pub const fn not_eof(mut opcode: OpCodeInfo) -> OpCodeInfo { opcode } -pub const fn size(mut opcode: OpCodeInfo) -> OpCodeInfo { - opcode.size = N; +/// Immediate bytes after opcode. +pub const fn imm_size(mut opcode: OpCodeInfo) -> OpCodeInfo { + opcode.immediate_size = N; opcode } @@ -469,38 +474,38 @@ opcodes! { 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>, size<2>; - 0x61 => PUSH2 => stack::push::<2, H> => stack_io<0, 1>, size<3>; - 0x62 => PUSH3 => stack::push::<3, H> => stack_io<0, 1>, size<4>; - 0x63 => PUSH4 => stack::push::<4, H> => stack_io<0, 1>, size<5>; - 0x64 => PUSH5 => stack::push::<5, H> => stack_io<0, 1>, size<6>; - 0x65 => PUSH6 => stack::push::<6, H> => stack_io<0, 1>, size<7>; - 0x66 => PUSH7 => stack::push::<7, H> => stack_io<0, 1>, size<8>; - 0x67 => PUSH8 => stack::push::<8, H> => stack_io<0, 1>, size<9>; - 0x68 => PUSH9 => stack::push::<9, H> => stack_io<0, 1>, size<10>; - 0x69 => PUSH10 => stack::push::<10, H> => stack_io<0, 1>, size<11>; - 0x6A => PUSH11 => stack::push::<11, H> => stack_io<0, 1>, size<12>; - 0x6B => PUSH12 => stack::push::<12, H> => stack_io<0, 1>, size<13>; - 0x6C => PUSH13 => stack::push::<13, H> => stack_io<0, 1>, size<14>; - 0x6D => PUSH14 => stack::push::<14, H> => stack_io<0, 1>, size<15>; - 0x6E => PUSH15 => stack::push::<15, H> => stack_io<0, 1>, size<16>; - 0x6F => PUSH16 => stack::push::<16, H> => stack_io<0, 1>, size<17>; - 0x70 => PUSH17 => stack::push::<17, H> => stack_io<0, 1>, size<18>; - 0x71 => PUSH18 => stack::push::<18, H> => stack_io<0, 1>, size<19>; - 0x72 => PUSH19 => stack::push::<19, H> => stack_io<0, 1>, size<20>; - 0x73 => PUSH20 => stack::push::<20, H> => stack_io<0, 1>, size<21>; - 0x74 => PUSH21 => stack::push::<21, H> => stack_io<0, 1>, size<22>; - 0x75 => PUSH22 => stack::push::<22, H> => stack_io<0, 1>, size<23>; - 0x76 => PUSH23 => stack::push::<23, H> => stack_io<0, 1>, size<24>; - 0x77 => PUSH24 => stack::push::<24, H> => stack_io<0, 1>, size<25>; - 0x78 => PUSH25 => stack::push::<25, H> => stack_io<0, 1>, size<26>; - 0x79 => PUSH26 => stack::push::<26, H> => stack_io<0, 1>, size<27>; - 0x7A => PUSH27 => stack::push::<27, H> => stack_io<0, 1>, size<28>; - 0x7B => PUSH28 => stack::push::<28, H> => stack_io<0, 1>, size<29>; - 0x7C => PUSH29 => stack::push::<29, H> => stack_io<0, 1>, size<30>; - 0x7D => PUSH30 => stack::push::<30, H> => stack_io<0, 1>, size<31>; - 0x7E => PUSH31 => stack::push::<31, H> => stack_io<0, 1>, size<32>; - 0x7F => PUSH32 => stack::push::<32, H> => stack_io<0, 1>, size<33>; + 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<0, 1>; 0x81 => DUP2 => stack::dup::<2, H> => stack_io<0, 1>; @@ -585,7 +590,7 @@ opcodes! { // 0xCE // 0xCF 0xD0 => DATALOAD => data::data_load => stack_io<1, 1>; - 0xD1 => DATALOADN => data::data_loadn => stack_io<0, 1>, size<3>; + 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 @@ -600,15 +605,15 @@ opcodes! { // 0xDD // 0xDE // 0xDF - 0xE0 => RJUMP => control::rjump => stack_io<0, 0>, size<3>; - 0xE1 => RJUMPI => control::rjumpi => stack_io<1, 0>, size<3>; - 0xE2 => RJUMPV => control::rjumpv => stack_io<1, 0>, size<3>; - 0xE3 => CALLF => control::callf => stack_io<0, 0>, size<3>; + 0xE0 => RJUMP => control::rjump => stack_io<0, 0>, imm_size<2>; + 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>, size<3>; - 0xE6 => DUPN => stack::dupn => stack_io<0, 0>, size<2>; - 0xE7 => SWAPN => stack::swapn => stack_io<0, 0>, size<2>; - 0xE8 => EXCHANGE => stack::exchange => stack_io<0, 0>, size<2>; + 0xE5 => JUMPF => control::jumpf => stack_io<0, 0>, imm_size<2>; + 0xE6 => DUPN => stack::dupn => stack_io<0, 0>, 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 diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index af55704075..ae63862c2b 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -1,13 +1,15 @@ -use revm_primitives::eof::TypesSection; -use revm_primitives::{Bytes, Eof, LegacyAnalyzedBytecode}; - -use crate::primitives::{ - bitvec::prelude::{bitvec, BitVec, Lsb0}, - legacy::JumpTable, - Bytecode, +use crate::{ + instructions::utility::read_u16, + opcode, + primitives::{ + bitvec::prelude::{bitvec, BitVec, Lsb0}, + eof::TypesSection, + legacy::JumpTable, + Bytecode, Bytes, Eof, LegacyAnalyzedBytecode, + }, + OpCode, OPCODE_INFO_JUMPTABLE, STACK_LIMIT, }; -use crate::{opcode, OPCODE_INFO_JUMPTABLE}; -use std::sync::Arc; +use std::{sync::Arc, vec, vec::Vec}; /// Perform bytecode analysis. /// @@ -92,6 +94,10 @@ pub fn validate_eof(eof: &Eof) -> Result<(), ()> { Ok(()) } +/// Validates that: +/// * All instructions are valid. +/// * It ends with a terminating instruction or RJUMP. +/// pub fn validate_eof_bytecode(code: &[u8], types: &TypesSection) -> Result<(), ()> { let max_stack_size = types.inputs as u16; let stack_size = types.inputs as u16; @@ -115,7 +121,7 @@ pub fn validate_eof_bytecode(code: &[u8], types: &TypesSection) -> Result<(), () }; // check if the size of the opcode is within the bounds of the code - if unsafe { iter.add(opcode.size as usize - 1) } > end { + if unsafe { iter.add(opcode.immediate_size as usize - 1) } > end { return Err(()); } @@ -169,25 +175,188 @@ pub fn validate_eof_bytecode(code: &[u8], types: &TypesSection) -> Result<(), () } /// Validate stack requirements and if all codes sections are used. -pub fn validate_stack_requirement(codes: &[u8]) -> Result<(), ()> { +/// +/// 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_stack_requirement( + codes: &[u8], + this_types_index: usize, + types: &[TypesSection], +) -> Result<(), ()> { #[derive(Copy, Clone)] - struct StackInfo { - min: u16, - max: u16, + struct StackIO { + pub min: u16, + pub max: u16, + } + + impl StackIO { + pub fn next(&self, diff: i16) -> Self { + Self { + min: self.min + diff as u16, + max: self.max + diff as u16, + } + } } - let mut code_stack_access: Vec> = vec![None; codes.len()]; - let mut worklist: Vec = Vec::new(); - while let Some(workitem) = worklist.pop() {} + impl Default for StackIO { + fn default() -> Self { + Self { + min: u16::MAX, + max: 0, + } + } + } + + // Stack access information for each instruction section. + let mut code_stack_access: Vec = vec![Default::default(); codes.len()]; + + // Set first instruction min and max stack requirement as a this code section input. + let this_types = &types[this_types_index]; + code_stack_access[0] = StackIO { + min: this_types.inputs as u16, + max: this_types.inputs as u16, + }; + + let max_stack_height = 0; + let mut i = 0; + while i < codes.len() { + let opcode = codes[i]; + + let Some(info) = OpCode::new(opcode).map(|i| i.info()) else { + panic!("Opcode validity is checked.") + }; + + let mut stack_i = info.inputs as u16; + let mut stack_io_diff = info.io_diff() as i16; + + let stack_io = code_stack_access[i]; + + // Jump over intermediate data and set min/max to zero. + match opcode { + opcode::CALLF => { + let code_id = read_u16(unsafe { codes.as_ptr().add(i + 1) }) as usize; + let types = &types[code_id]; + // stack input for this opcode is the input of the called code. + stack_i = types.inputs as u16; + + // we decrement types.inputs as they are considered send to the called code. + // and included in types.max_stack_size. + if stack_io.max - stack_i + types.max_stack_size > STACK_LIMIT as u16 { + // if stack max items + called code max stack size + return Err(()); + } + stack_io_diff = types.io_diff() as i16; + } + opcode::JUMPF => { + let code_id = read_u16(unsafe { codes.as_ptr().add(i + 1) }) as usize; + + let target_types = &types[code_id]; + + // we decrement types.inputs as they are considered send to the called code. + // and included in types.max_stack_size. + if stack_io.max - target_types.inputs as u16 + target_types.max_stack_size + > STACK_LIMIT as u16 + { + // stack overflow + return Err(()); + } + + stack_io_diff = 0; + if target_types.outputs == 0 { + // if it is not returning + stack_i = target_types.inputs as u16; + } else { + // check if target code produces enough outputs. + if target_types.outputs < this_types.outputs { + return Err(()); + } + + // TOOD(EOF) check overflows. + stack_i = (target_types.outputs as i16 + this_types.io_diff()) as u16; + + // if this instruction max + target_types max is more then stack limit. + if stack_io.max + stack_i > STACK_LIMIT as u16 { + return Err(()); + } + } + } + opcode::RETF => { + stack_i = this_types.outputs as u16; + if stack_io.max > stack_i { + // stack_higher_than_outputs_required + return Err(()); + } + } + opcode::DUPN => { + stack_i = codes[i + 1] as u16 + 1; + stack_io_diff = 1; + } + opcode::SWAPN => { + stack_i = codes[i + 1] as u16 + 2; + } + opcode::EXCHANGE => { + let imm = codes[i + 1]; + let n = (imm >> 4) + 1; + let m = (imm & 0x0F) + 1; + stack_i = n as u16 + m as u16; + } + _ => {} + } + + if stack_io.min < stack_i { + // should have at least min items for stack input + return Err(()); + } + + // next item stack io; + let mut next_stack_io = stack_io.next(stack_io_diff); + + let mut imm_size = info.immediate_size as usize; + if opcode == opcode::RJUMPV { + // code validation is already done and we can access codes[workitem + 1] safely. + imm_size += codes[i + 1] as usize * 2; + } + + // Nulify max stack if it is a terminating opcode. + if info.is_terminating_opcode { + next_stack_io.max = 0; + next_stack_io.min = 0; + } + + // next instruction index. + i += imm_size + 1; + + // check if opcode is terminating or it is RJUMP (to previous dest). + if info.is_terminating_opcode || opcode == opcode::RJUMP { + // if it is not a jump instruction, we set next stack io. + code_stack_access[i + 1] = next_stack_io; + } + + // if next instruction is out of bounds, break. Terminal instructions are already handled. + if i >= codes.len() { + break; + } + + //match opcode {} + + // check next instruction, break if it is out of bounds. + } // Iterate over accessed code, error on not accessed opcode and return max stack requirement. let mut max_stack_requirement = 0; for opcode in code_stack_access { - if let Some(opcode) = opcode { - max_stack_requirement = core::cmp::max(opcode.max, max_stack_requirement); - } else { + if opcode.min == u16::MAX { + // opcode not accessed. return Err(()); } + max_stack_requirement = core::cmp::max(opcode.max, max_stack_requirement); } Ok(()) } diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs index 22cff0915c..8f7f9204bb 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -1,5 +1,6 @@ use super::decode_helpers::{consume_u16, consume_u8}; +/// TODO(EOF) Chekc if max_stack_size >= inputs. #[derive(Debug, Clone, Default, Hash, PartialEq, Eq, Copy)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TypesSection { @@ -14,6 +15,12 @@ pub struct TypesSection { } impl TypesSection { + /// Return the difference between inputs and outputs. + #[inline] + pub fn io_diff(&self) -> i16 { + self.outputs as i16 - self.inputs as i16 + } + #[inline] pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), ()> { let (input, inputs) = consume_u8(input)?; From d28122e2816bf7a4add0d9e87c42815b7f2bad91 Mon Sep 17 00:00:00 2001 From: rakita Date: Sat, 23 Mar 2024 01:29:09 +0100 Subject: [PATCH 29/54] EOF Bytecode validity --- .../interpreter/src/interpreter/analysis.rs | 154 +++++++++++++++--- 1 file changed, 128 insertions(+), 26 deletions(-) diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index ae63862c2b..ed1c79ed01 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -1,5 +1,5 @@ use crate::{ - instructions::utility::read_u16, + instructions::utility::{read_i16, read_u16}, opcode, primitives::{ bitvec::prelude::{bitvec, BitVec, Lsb0}, @@ -11,6 +11,8 @@ use crate::{ }; 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. @@ -98,42 +100,146 @@ pub fn validate_eof(eof: &Eof) -> Result<(), ()> { /// * All instructions are valid. /// * It ends with a terminating instruction or RJUMP. /// -pub fn validate_eof_bytecode(code: &[u8], types: &TypesSection) -> Result<(), ()> { - let max_stack_size = types.inputs as u16; - let stack_size = types.inputs as u16; - - let mut iter = code.as_ptr(); - let end = code.as_ptr().wrapping_add(code.len()); - - let is_returning = false; +pub fn validate_eof_bytecode( + code: &[u8], + accessed_codes: &mut [bool], + types: &[TypesSection], +) -> Result<(), ()> { + #[derive(Copy, Default, Clone)] + pub struct BytecodeMark { + /// 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. + has_forward_jump: bool, + } // all bytes that are intermediate. - let jumptable = vec![false; code.len()]; + let mut jumps = vec![BytecodeMark::default(); code.len()]; + let mut is_after_termination = false; + + let mut i = 0; // We can check validity and jump destinations in one pass. - while iter < end { - let op = unsafe { *iter }; + while i < code.len() { + let op = code[i]; let opcode_info = &OPCODE_INFO_JUMPTABLE[op as usize]; + let this_jump = jumps[i]; // Unknown opcode let Some(opcode) = opcode_info else { + // err unknown opcode. return Err(()); }; - // check if the size of the opcode is within the bounds of the code - if unsafe { iter.add(opcode.immediate_size as usize - 1) } > end { + if !opcode.is_eof { + // Opcode is disabled in EOF return Err(()); } - match op { - opcode::RJUMPV | opcode::RJUMP | opcode::RJUMPI => { - // check jump destination with bytecode size. + // Opcodes after termination should be accessed by forward jumps. + if is_after_termination && this_jump.has_forward_jump { + // opcode after termination was not accessed. + return Err(()); + } + is_after_termination = opcode.is_terminating_opcode; + + // mark immediates as non-jumpable. RJUMPV is special case covered later. + if opcode.immediate_size != 0 { + // check if the opcode immediates are within the bounds of the code + if i + opcode.immediate_size as usize > code.len() { + // Malfunctional code + return Err(()); + } + + // mark immediate bytes as non-jumpable. + for imm in 1..opcode.immediate_size as usize + 1 { + // SAFETY: immediate size is checked above. + let jumptable = &mut jumps[imm]; + if jumptable.has_forward_jump { + // There is a jump to the immediate bytes. + return Err(()); + } + jumptable.is_immediate = true; + } + } + let mut additional_immediates = 0; + // get absolute jumpdest from RJUMP, RJUMPI and RJUMPV + let absolute_jumpdest = match op { + opcode::RJUMP | opcode::RJUMPI => { + let offset = read_i16(unsafe { code.as_ptr().add(i + 1) }) as isize; + if offset == 0 { + // jump immediate instruction is not allowed. + return Err(()); + } + vec![offset + 3 + i as isize] + } + opcode::RJUMPV => { + let max_index = code[i + 1] as usize; + additional_immediates = (1 + max_index) * 2; + + // Max index can't be zero as it becomes RJUMPI. + if max_index == 0 { + return Err(()); + } - // check if jump destination is valid + // +1 is for max_index byte, and max_index+1 is to get size of vtable. + if i + 1 + additional_immediates >= code.len() { + // Malfunctional code RJUMPV vtable is not complete + return Err(()); + } + + let mut jumps = Vec::with_capacity(max_index); + for vtablei in 0..max_index { + let offset = + read_i16(unsafe { code.as_ptr().add(i + 2 + 2 * vtablei) }) as isize; + if offset == 0 { + // jump immediate instruction is not allowed. + return Err(()); + } + jumps[vtablei] = offset + i as isize + 2 + additional_immediates as isize; + } + jumps + } + _ => vec![], + }; + + // check if jumpdest are correct. + for absolute_jump in absolute_jumpdest { + if absolute_jump < 0 { + // jump out of bounds. + return Err(()); + } + if absolute_jump > code.len() as isize { + // jump to out of bounds + return Err(()); + } + // fine to cast as bound 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(()); } + // for previous jumps we already marked them in is immediate. + target_jump.has_forward_jump = true; + } + + match op { opcode::CALLF => { - // check codes size. + let section_i = read_u16(unsafe { code.as_ptr().add(i + 1) }) as usize; // targeted code needs to have zero outputs (be non returning). + let Some(next_section) = types.get(section_i) else { + // code section out of bounds. + return Err(()); + }; + + if next_section.outputs == EOF_NON_RETURNING_FUNCTION { + // callf to non returning function is not allowed + return Err(()); + } + accessed_codes[section_i] = true; } opcode::RETF => { // check if it is returning. TODO here @@ -161,13 +267,9 @@ pub fn validate_eof_bytecode(code: &[u8], types: &TypesSection) -> Result<(), () // } } - // iterate over opcodes - - if max_stack_size != types.max_stack_size { - return Err(()); - } - - if stack_size != types.outputs as u16 { + // last opcode should be terminating + if !is_after_termination { + // wrong termination. return Err(()); } From 77939ac21ad08baae85da3b32a760312f61e1f0d Mon Sep 17 00:00:00 2001 From: rakita Date: Sat, 23 Mar 2024 02:04:16 +0100 Subject: [PATCH 30/54] insturction and jump validation seems good --- .../interpreter/src/interpreter/analysis.rs | 68 ++++++++++++------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index ed1c79ed01..9fe08869c9 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -84,6 +84,7 @@ pub fn validate_eof(eof: &Eof) -> Result<(), ()> { { types.validate()?; } + validate_eof_codes(&eof)?; // iterate over containers, convert them to Eof and add to analyze_eof for container in eof.body.container_section { @@ -96,17 +97,35 @@ pub fn validate_eof(eof: &Eof) -> Result<(), ()> { Ok(()) } +/// Validate EOF +pub fn validate_eof_codes(eof: &Eof) -> Result<(), ()> { + // TODO(EOF) accessed codes needs to be called in order. + // this is not correct rn + let mut accessed_codes = vec![false; eof.body.code_section.len()]; + for codes in eof.body.code_section.iter() { + validate_eof_code( + &codes, + &mut accessed_codes, + eof.header.data_size as usize, + &eof.body.types_section, + )?; + } + + Ok(()) +} + /// Validates that: /// * All instructions are valid. /// * It ends with a terminating instruction or RJUMP. /// -pub fn validate_eof_bytecode( +pub fn validate_eof_code( code: &[u8], accessed_codes: &mut [bool], + data_size: usize, types: &[TypesSection], ) -> Result<(), ()> { #[derive(Copy, Default, Clone)] - pub struct BytecodeMark { + struct BytecodeMark { /// 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 @@ -116,18 +135,17 @@ pub fn validate_eof_bytecode( // all bytes that are intermediate. let mut jumps = vec![BytecodeMark::default(); code.len()]; - let mut is_after_termination = false; let mut i = 0; // We can check validity and jump destinations in one pass. while i < code.len() { let op = code[i]; - let opcode_info = &OPCODE_INFO_JUMPTABLE[op as usize]; + let opcode = &OPCODE_INFO_JUMPTABLE[op as usize]; let this_jump = jumps[i]; // Unknown opcode - let Some(opcode) = opcode_info else { + let Some(opcode) = opcode else { // err unknown opcode. return Err(()); }; @@ -241,30 +259,28 @@ pub fn validate_eof_bytecode( } accessed_codes[section_i] = true; } - opcode::RETF => { - // check if it is returning. TODO here + opcode::JUMPF => { + let section_i = read_u16(unsafe { code.as_ptr().add(i + 1) }) as usize; + // targeted code needs to have zero outputs (be non returning). + let Some(next_section) = types.get(section_i) else { + // code section out of bounds. + return Err(()); + }; + // if it is not returning JUMPF becomes terminating opcode. + is_after_termination = next_section.outputs == EOF_NON_RETURNING_FUNCTION; + accessed_codes[section_i] = true; + } + opcode::DATALOADN => { + let index = read_u16(unsafe { code.as_ptr().add(i + 1) }) as usize; + if data_size < 32 || index as isize > data_size as isize - 32 { + // data load out of bounds. + return Err(()); + } } _ => {} } - - // if let Some(jump) = opcode_info.jump { - // eof_table[jump as usize] += 1; - // } - - // if opcode::JUMPDEST == opcode { - // // SAFETY: jumps are max length of the code - // unsafe { jumps.set_unchecked(iterator.offset_from(start) as usize, true) } - // iterator = unsafe { iterator.offset(1) }; - // } else { - // let push_offset = opcode.wrapping_sub(opcode::PUSH1); - // if push_offset < 32 { - // // SAFETY: iterator access range is checked in the while loop - // iterator = unsafe { iterator.offset((push_offset + 2) as isize) }; - // } else { - // // SAFETY: iterator access range is checked in the while loop - // iterator = unsafe { iterator.offset(1) }; - // } - // } + // additional immediates are from RJUMPV vtable. + i += 1 + opcode.immediate_size as usize + additional_immediates; } // last opcode should be terminating From 28d1f7428c77ea730035e1c21e62ed2d174b216a Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 26 Mar 2024 02:16:43 +0100 Subject: [PATCH 31/54] merged eof validate function --- crates/interpreter/src/instructions/opcode.rs | 48 +- .../interpreter/src/interpreter/analysis.rs | 455 +++++++++--------- .../src/bytecode/eof/types_section.rs | 4 +- crates/primitives/src/specification.rs | 2 +- 4 files changed, 260 insertions(+), 249 deletions(-) diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index f40cde515d..fdf7451b7c 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -671,21 +671,21 @@ mod tests { } #[test] - fn test_opcode_size() { + 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] = 3; - opcodes[RJUMP as usize] = 3; - opcodes[RJUMPI as usize] = 3; - opcodes[RJUMPV as usize] = 3; - opcodes[CALLF as usize] = 3; - opcodes[JUMPF as usize] = 3; - opcodes[DUPN as usize] = 2; - opcodes[SWAPN as usize] = 2; - opcodes[EXCHANGE as usize] = 2; + 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] @@ -717,8 +717,30 @@ mod tests { } #[test] - pub fn test_terminating_opcodes() { - // TODO check JUMPF - let terminating = [RETF, JUMPF]; + fn test_terminating_opcodes() { + let terminating = [ + RETF, + REVERT, + RETURN, + INVALID, + SELFDESTRUCT, + RETURNCONTRACT, + STOP, + ]; + let mut opcodes = [false; 256]; + for terminating in terminating.iter() { + opcodes[*terminating as usize] = true; + } + + for (i, opcode) in OPCODE_INFO_JUMPTABLE.clone().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/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 9fe08869c9..8dd7f0a69f 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -1,3 +1,5 @@ +use revm_primitives::HashSet; + use crate::{ instructions::utility::{read_i16, read_u16}, opcode, @@ -64,6 +66,12 @@ fn analyze(code: &[u8]) -> JumpTable { JumpTable(Arc::new(jumps)) } +pub fn validate_raw_eof(bytecode: Bytes) -> Result { + let eof = Eof::decode(bytecode)?; + validate_eof(&eof)?; + Ok(eof) +} + /// Validate Eof structures. /// /// do perf test on: @@ -72,24 +80,17 @@ fn analyze(code: &[u8]) -> JumpTable { /// bytecode iteration. pub fn validate_eof(eof: &Eof) -> Result<(), ()> { // clone is cheat as it is Bytes and a header. - let mut analyze_eof = vec![eof.clone()]; - - while let Some(eof) = analyze_eof.pop() { - // iterate over types and code - for (types, bytes) in eof - .body - .types_section - .iter() - .zip(eof.body.code_section.iter()) - { + let mut queue = vec![eof.clone()]; + + while let Some(eof) = queue.pop() { + // iterate over types + for types in &eof.body.types_section { types.validate()?; } validate_eof_codes(&eof)?; - // iterate over containers, convert them to Eof and add to analyze_eof for container in eof.body.container_section { - let container_eof = Eof::decode(container)?; - analyze_eof.push(container_eof); + queue.push(Eof::decode(container)?); } } @@ -99,52 +100,102 @@ pub fn validate_eof(eof: &Eof) -> Result<(), ()> { /// Validate EOF pub fn validate_eof_codes(eof: &Eof) -> Result<(), ()> { - // TODO(EOF) accessed codes needs to be called in order. - // this is not correct rn - let mut accessed_codes = vec![false; eof.body.code_section.len()]; - for codes in eof.body.code_section.iter() { - validate_eof_code( - &codes, - &mut accessed_codes, + let mut queued_codes = vec![false; eof.body.code_section.len()]; + // first section is default one. + queued_codes[0] = true; + // 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.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. + queued_codes.into_iter().find(|&x| x == false).ok_or(())?; + Ok(()) } /// 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], - accessed_codes: &mut [bool], data_size: usize, + this_types_index: usize, types: &[TypesSection], -) -> Result<(), ()> { - #[derive(Copy, Default, Clone)] - struct BytecodeMark { +) -> Result, ()> { + let mut accessed_codes = HashSet::::new(); + let this_types = &types[this_types_index]; + + #[derive(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. - has_forward_jump: bool, + 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, + } + + impl Default for InstructionInfo { + fn default() -> Self { + Self { + is_immediate: false, + is_jumpdest: false, + smallest: i32::MAX, + biggest: i32::MIN, + } + } } // all bytes that are intermediate. - let mut jumps = vec![BytecodeMark::default(); code.len()]; + 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 this_jump = jumps[i]; + let this_instruction = &mut jumps[i]; + 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; - // Unknown opcode let Some(opcode) = opcode else { // err unknown opcode. return Err(()); @@ -156,15 +207,15 @@ pub fn validate_eof_code( } // Opcodes after termination should be accessed by forward jumps. - if is_after_termination && this_jump.has_forward_jump { + if is_after_termination && this_instruction.is_jumpdest { // opcode after termination was not accessed. return Err(()); } is_after_termination = opcode.is_terminating_opcode; - // mark immediates as non-jumpable. RJUMPV is special case covered later. + // mark immediate as non-jumpable. RJUMPV is special case covered later. if opcode.immediate_size != 0 { - // check if the opcode immediates are within the bounds of the code + // 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(()); @@ -173,36 +224,44 @@ pub fn validate_eof_code( // mark immediate bytes as non-jumpable. for imm in 1..opcode.immediate_size as usize + 1 { // SAFETY: immediate size is checked above. - let jumptable = &mut jumps[imm]; - if jumptable.has_forward_jump { + let jumptable = &mut jumps[i + imm]; + if jumptable.is_jumpdest { // There is a jump to the immediate bytes. return Err(()); } jumptable.is_immediate = true; } } - let mut additional_immediates = 0; - // get absolute jumpdest from RJUMP, RJUMPI and RJUMPV - let absolute_jumpdest = match op { + // 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 = read_i16(unsafe { code.as_ptr().add(i + 1) }) as isize; if offset == 0 { // jump immediate instruction is not allowed. return Err(()); } - vec![offset + 3 + i as isize] + absolute_jumpdest = vec![offset + 3 + i as isize] } opcode::RJUMPV => { + // code length for RJUMPV is checked with immediate size. let max_index = code[i + 1] as usize; - additional_immediates = (1 + max_index) * 2; + // and max_index+1 is to get size of vtable as index starts from 0. + rjumpv_additional_immediates = (1 + max_index) * 2; // Max index can't be zero as it becomes RJUMPI. if max_index == 0 { return Err(()); } - // +1 is for max_index byte, and max_index+1 is to get size of vtable. - if i + 1 + additional_immediates >= code.len() { + // +1 is for max_index byte + if i + 1 + rjumpv_additional_immediates >= code.len() { // Malfunctional code RJUMPV vtable is not complete return Err(()); } @@ -215,266 +274,196 @@ pub fn validate_eof_code( // jump immediate instruction is not allowed. return Err(()); } - jumps[vtablei] = offset + i as isize + 2 + additional_immediates as isize; + jumps[vtablei] = + offset + i as isize + 2 + rjumpv_additional_immediates as isize; } - jumps - } - _ => vec![], - }; - - // check if jumpdest are correct. - for absolute_jump in absolute_jumpdest { - if absolute_jump < 0 { - // jump out of bounds. - return Err(()); - } - if absolute_jump > code.len() as isize { - // jump to out of bounds - return Err(()); + absolute_jumpdest = jumps } - // fine to cast as bound 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(()); - } - // for previous jumps we already marked them in is immediate. - target_jump.has_forward_jump = true; - } - - match op { opcode::CALLF => { let section_i = read_u16(unsafe { code.as_ptr().add(i + 1) }) as usize; - // targeted code needs to have zero outputs (be non returning). - let Some(next_section) = types.get(section_i) else { + let Some(target_types) = types.get(section_i) else { // code section out of bounds. return Err(()); }; - if next_section.outputs == EOF_NON_RETURNING_FUNCTION { + if target_types.outputs == EOF_NON_RETURNING_FUNCTION { // callf to non returning function is not allowed return Err(()); } - accessed_codes[section_i] = true; - } - opcode::JUMPF => { - let section_i = read_u16(unsafe { code.as_ptr().add(i + 1) }) as usize; - // targeted code needs to have zero outputs (be non returning). - let Some(next_section) = types.get(section_i) else { - // code section out of bounds. - return Err(()); - }; - // if it is not returning JUMPF becomes terminating opcode. - is_after_termination = next_section.outputs == EOF_NON_RETURNING_FUNCTION; - accessed_codes[section_i] = true; - } - opcode::DATALOADN => { - let index = read_u16(unsafe { code.as_ptr().add(i + 1) }) as usize; - if data_size < 32 || index as isize > data_size as isize - 32 { - // data load out of bounds. - return Err(()); - } - } - _ => {} - } - // additional immediates are from RJUMPV vtable. - i += 1 + opcode.immediate_size as usize + additional_immediates; - } - - // last opcode should be terminating - if !is_after_termination { - // wrong termination. - return Err(()); - } - - Ok(()) -} - -/// 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_stack_requirement( - codes: &[u8], - this_types_index: usize, - types: &[TypesSection], -) -> Result<(), ()> { - #[derive(Copy, Clone)] - struct StackIO { - pub min: u16, - pub max: u16, - } - - impl StackIO { - pub fn next(&self, diff: i16) -> Self { - Self { - min: self.min + diff as u16, - max: self.max + diff as u16, - } - } - } - - impl Default for StackIO { - fn default() -> Self { - Self { - min: u16::MAX, - max: 0, - } - } - } - - // Stack access information for each instruction section. - let mut code_stack_access: Vec = vec![Default::default(); codes.len()]; - - // Set first instruction min and max stack requirement as a this code section input. - let this_types = &types[this_types_index]; - code_stack_access[0] = StackIO { - min: this_types.inputs as u16, - max: this_types.inputs as u16, - }; - - let max_stack_height = 0; - let mut i = 0; - while i < codes.len() { - let opcode = codes[i]; - - let Some(info) = OpCode::new(opcode).map(|i| i.info()) else { - panic!("Opcode validity is checked.") - }; - - let mut stack_i = info.inputs as u16; - let mut stack_io_diff = info.io_diff() as i16; - - let stack_io = code_stack_access[i]; - - // Jump over intermediate data and set min/max to zero. - match opcode { - opcode::CALLF => { - let code_id = read_u16(unsafe { codes.as_ptr().add(i + 1) }) as usize; - let types = &types[code_id]; // stack input for this opcode is the input of the called code. - stack_i = types.inputs as u16; - - // we decrement types.inputs as they are considered send to the called code. - // and included in types.max_stack_size. - if stack_io.max - stack_i + types.max_stack_size > STACK_LIMIT as u16 { + stack_requirement = target_types.inputs as i32; + // stack diff depends on input/output of the called code. + stack_io_diff = target_types.io_diff() as i32; + // 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(()); } - stack_io_diff = types.io_diff() as i16; } opcode::JUMPF => { - let code_id = read_u16(unsafe { codes.as_ptr().add(i + 1) }) as usize; - - let target_types = &types[code_id]; + let target_index = read_u16(unsafe { 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(()); + }; // we decrement types.inputs as they are considered send to the called code. // and included in types.max_stack_size. - if stack_io.max - target_types.inputs as u16 + target_types.max_stack_size - > STACK_LIMIT as u16 + if this_instruction.biggest - target_types.inputs as i32 + + target_types.max_stack_size as i32 + > STACK_LIMIT as i32 { // stack overflow return Err(()); } - stack_io_diff = 0; - if target_types.outputs == 0 { + accessed_codes.insert(target_index); + + if target_types.outputs == EOF_NON_RETURNING_FUNCTION { // if it is not returning - stack_i = target_types.inputs as u16; + stack_requirement = target_types.inputs as i32; + // if it is not returning JUMPF becomes terminating opcode. + is_after_termination = true; } else { // check if target code produces enough outputs. if target_types.outputs < this_types.outputs { return Err(()); } - // TOOD(EOF) check overflows. - stack_i = (target_types.outputs as i16 + this_types.io_diff()) as u16; + // TODO(EOF) stack requirements for this opcode. + stack_requirement = (target_types.outputs as i32 + this_types.io_diff()) as i32; // if this instruction max + target_types max is more then stack limit. - if stack_io.max + stack_i > STACK_LIMIT as u16 { + if this_instruction.biggest + stack_requirement > STACK_LIMIT as i32 { return Err(()); } } } + opcode::DATALOADN => { + let index = read_u16(unsafe { 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(()); + } + } opcode::RETF => { - stack_i = this_types.outputs as u16; - if stack_io.max > stack_i { + stack_requirement = this_types.outputs as i32; + if this_instruction.biggest > stack_requirement { // stack_higher_than_outputs_required return Err(()); } } opcode::DUPN => { - stack_i = codes[i + 1] as u16 + 1; + stack_requirement = code[i + 1] as i32 + 1; stack_io_diff = 1; } opcode::SWAPN => { - stack_i = codes[i + 1] as u16 + 2; + stack_requirement = code[i + 1] as i32 + 2; } opcode::EXCHANGE => { - let imm = codes[i + 1]; + let imm = code[i + 1]; let n = (imm >> 4) + 1; let m = (imm & 0x0F) + 1; - stack_i = n as u16 + m as u16; + stack_requirement = n as i32 + m as i32; } _ => {} } - if stack_io.min < stack_i { - // should have at least min items for stack input + // 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(()); } - // next item stack io; - let mut next_stack_io = stack_io.next(stack_io_diff); - - let mut imm_size = info.immediate_size as usize; - if opcode == opcode::RJUMPV { - // code validation is already done and we can access codes[workitem + 1] safely. - imm_size += codes[i + 1] as usize * 2; - } + // 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(()); + } + if absolute_jump >= code.len() as isize { + // jump to out of bounds + return Err(()); + } + // fine to cast as bounds are checked. + let absolute_jump = absolute_jump as usize; - // Nulify max stack if it is a terminating opcode. - if info.is_terminating_opcode { - next_stack_io.max = 0; - next_stack_io.min = 0; - } + let target_jump = &mut jumps[absolute_jump]; + if target_jump.is_immediate { + // Jump target is immediate byte. + return Err(()); + } - // next instruction index. - i += imm_size + 1; + // needed to mark forward jumps. It does not do anything for backward jumps. + target_jump.is_jumpdest = true; - // check if opcode is terminating or it is RJUMP (to previous dest). - if info.is_terminating_opcode || opcode == opcode::RJUMP { - // if it is not a jump instruction, we set next stack io. - code_stack_access[i + 1] = next_stack_io; + if absolute_jump < i { + // backward jumps should have same smallest and biggest stack items. + if this_instruction.biggest != target_jump.biggest { + // wrong jumpdest. + return Err(()); + } + if this_instruction.smallest != target_jump.smallest { + // wrong jumpdest. + return Err(()); + } + } 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, this_instruction.smallest); + target_jump.biggest = core::cmp::max(target_jump.biggest, this_instruction.biggest); + } } - // if next instruction is out of bounds, break. Terminal instructions are already handled. - if i >= codes.len() { - break; - } + next_smallest = this_instruction.smallest + stack_io_diff; + next_biggest = this_instruction.smallest + stack_io_diff; - //match opcode {} + // additional immediate are from RJUMPV vtable. + i += 1 + opcode.immediate_size as usize + rjumpv_additional_immediates; + } - // check next instruction, break if it is out of bounds. + // last opcode should be terminating + if !is_after_termination { + // wrong termination. + return Err(()); } - // Iterate over accessed code, error on not accessed opcode and return max stack requirement. + // TODO integrate max so we dont need to iterate again let mut max_stack_requirement = 0; - for opcode in code_stack_access { - if opcode.min == u16::MAX { - // opcode not accessed. - return Err(()); - } - max_stack_requirement = core::cmp::max(opcode.max, max_stack_requirement); + for opcode in jumps { + max_stack_requirement = core::cmp::max(opcode.biggest, max_stack_requirement); } - Ok(()) + + Ok(accessed_codes) } + +// For secquential opcodes min and max values are same. +// /// Difference is with jumps, +// #[derive(Copy, Clone)] +// struct StackNum { +// /// 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, +// } + +// impl StackNum { +// fn next(&self, diff: i16) -> Self { +// Self { +// smallest: self.smallest + diff as i32, +// biggest: self.biggest + diff as i32, +// } +// } +// fn merge_jumpdest(&mut self, other: Self) { +// self.smallest = core::cmp::min(self.smallest, other.smallest); +// self.biggest = core::cmp::max(self.biggest, other.biggest); +// } +// } diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs index 8f7f9204bb..3dae1a6984 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -17,8 +17,8 @@ pub struct TypesSection { impl TypesSection { /// Return the difference between inputs and outputs. #[inline] - pub fn io_diff(&self) -> i16 { - self.outputs as i16 - self.inputs as i16 + pub fn io_diff(&self) -> i32 { + self.outputs as i32 - self.inputs as i32 } #[inline] diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index 87703f7ecc..35010255cf 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -74,7 +74,7 @@ impl SpecId { Self::n(spec_id) } - pub fn is_enabled_in(&self, other: Self) -> bool { + pub const fn is_enabled_in(&self, other: Self) -> bool { Self::enabled(*self, other) } From 2db230a2d537c958f9b57bd231c6c22fdb79fbef Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 26 Mar 2024 13:25:57 +0100 Subject: [PATCH 32/54] EOP test runner, fex fixes --- Cargo.lock | 2 + crates/interpreter/Cargo.toml | 10 + crates/interpreter/src/instructions/opcode.rs | 8 +- .../interpreter/src/interpreter/analysis.rs | 218 +- .../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 + .../tests/EOFTests/ori/validInvalid.json | 677 +++++ crates/interpreter/tests/eof.rs | 119 + 13 files changed, 7125 insertions(+), 68 deletions(-) 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/ori/validInvalid.json create mode 100644 crates/interpreter/tests/eof.rs diff --git a/Cargo.lock b/Cargo.lock index 6109c96d01..95b122329f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2345,6 +2345,8 @@ version = "3.3.0" dependencies = [ "revm-primitives", "serde", + "serde_json", + "walkdir", ] [[package]] diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index e0c810d2a3..14c6a8a0d5 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/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index fdf7451b7c..7378499f0b 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -303,7 +303,7 @@ impl OpCodeInfo { } pub const fn io_diff(&self) -> i16 { - self.inputs as i16 - self.outputs as i16 + self.outputs as i16 - self.inputs as i16 } } @@ -465,7 +465,7 @@ opcodes! { 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>; + 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>; @@ -621,12 +621,12 @@ opcodes! { 0xED => CREATE4 => contract::txcreate:: => stack_io<5, 1>; 0xEE => RETURNCONTRACT => contract::return_contract:: => stack_io<0, 0>, terminating; // TODO(EOF) input/output // 0xEF - 0xF0 => CREATE => contract::create:: => stack_io<4, 1>; + 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<0, 0>, terminating; 0xF4 => DELEGATECALL => contract::delegate_call:: => stack_io<6, 1>, not_eof; - 0xF5 => CREATE2 => contract::create:: => stack_io<5, 1>; + 0xF5 => CREATE2 => contract::create:: => stack_io<5, 1>, not_eof; // 0xF6 0xF7 => RETURNDATALOAD => system::returndataload:: => stack_io<0, 0>; // TODO(EOF) impl 0xF8 => EXTCALL => contract::extcall:: => stack_io<4, 1>; diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 8dd7f0a69f..01ed5eb97a 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -66,8 +66,8 @@ fn analyze(code: &[u8]) -> JumpTable { JumpTable(Arc::new(jumps)) } -pub fn validate_raw_eof(bytecode: Bytes) -> Result { - let eof = Eof::decode(bytecode)?; +pub fn validate_raw_eof(bytecode: Bytes) -> Result { + let eof = Eof::decode(bytecode).map_err(|_| EofError::EofDecode)?; validate_eof(&eof)?; Ok(eof) } @@ -78,19 +78,21 @@ pub fn validate_raw_eof(bytecode: Bytes) -> Result { /// max eof containers /// max depth of containers. /// bytecode iteration. -pub fn validate_eof(eof: &Eof) -> Result<(), ()> { +pub fn validate_eof(eof: &Eof) -> Result<(), EofError> { // clone is cheat as it is Bytes and a header. let mut queue = vec![eof.clone()]; while let Some(eof) = queue.pop() { // iterate over types for types in &eof.body.types_section { - types.validate()?; + types + .validate() + .map_err(|_| EofError::InvalidTypesSection)?; } 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)?); + queue.push(Eof::decode(container).map_err(|_| EofError::EofDecode)?); } } @@ -99,7 +101,7 @@ pub fn validate_eof(eof: &Eof) -> Result<(), ()> { } /// Validate EOF -pub fn validate_eof_codes(eof: &Eof) -> Result<(), ()> { +pub fn validate_eof_codes(eof: &Eof) -> Result<(), EofError> { let mut queued_codes = vec![false; eof.body.code_section.len()]; // first section is default one. queued_codes[0] = true; @@ -122,13 +124,116 @@ pub fn validate_eof_codes(eof: &Eof) -> Result<(), ()> { } }); } - // iterate over accessed codes and check if all are accessed. - queued_codes.into_iter().find(|&x| x == false).ok_or(())?; + if queued_codes.into_iter().find(|&x| x == false).is_some() { + return Err(EofError::CodeSectionNotAccessed); + } Ok(()) } +/* + +//0x6001800100 +0x6001 PUSH1 +80 DUP1 +01 ADD +00 STOP + +// 0xef0001010004020001000504000000008000026001800100 +0xef00 magic +01 version +01 kind +0004 04 size +02 kind +0001 num of codes +0005 size of code +04 kind data +0000 size of data +00 terminator +00 inputs +80 non returning fn +0002 max stack elements +6001800100 + +0x6001 PUSH0 +80 +80 +80 +80 +80 +80 +f1 +00 + +*/ + +#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] +pub enum EofError { + TEST, + /// 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 [`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, + /// 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, + /// DATA load out of bounds. + DataLoadOutOfBounds, + /// TODO(EOF) check this error. + RETFBiggestStackNumMoreThenOutputs, + /// Stack requirement is more than smallest stack items. + StackUnderflow, + /// 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, + /// EofDecode error, + EofDecode, + /// Max stack element mismatch. + MaxStackMismatch, +} + +/* +0x6000 PUSH1 +e200 +00035b5b00600160015500 + + + */ + + /// Validates that: /// * All instructions are valid. /// * It ends with a terminating instruction or RJUMP. @@ -150,11 +255,11 @@ pub fn validate_eof_code( data_size: usize, this_types_index: usize, types: &[TypesSection], -) -> Result, ()> { +) -> Result, EofError> { let mut accessed_codes = HashSet::::new(); let this_types = &types[this_types_index]; - #[derive(Copy, Clone)] + #[derive(Debug, Copy, Clone)] struct InstructionInfo { /// Is immediate byte, jumps can't happen on this part of code. is_immediate: bool, @@ -198,27 +303,27 @@ pub fn validate_eof_code( let Some(opcode) = opcode else { // err unknown opcode. - return Err(()); + return Err(EofError::UnknownOpcode); }; if !opcode.is_eof { // Opcode is disabled in EOF - return Err(()); + return Err(EofError::OpcodeDisabled); } // 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(()); + return Err(EofError::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() { + if i + opcode.immediate_size as usize >= code.len() { // Malfunctional code - return Err(()); + return Err(EofError::MissingImmediateBytes); } // mark immediate bytes as non-jumpable. @@ -227,7 +332,7 @@ pub fn validate_eof_code( let jumptable = &mut jumps[i + imm]; if jumptable.is_jumpdest { // There is a jump to the immediate bytes. - return Err(()); + return Err(EofError::JumpToImmediateBytes); } jumptable.is_immediate = true; } @@ -245,7 +350,7 @@ pub fn validate_eof_code( let offset = read_i16(unsafe { code.as_ptr().add(i + 1) }) as isize; if offset == 0 { // jump immediate instruction is not allowed. - return Err(()); + return Err(EofError::JumpToImmediateBytes); } absolute_jumpdest = vec![offset + 3 + i as isize] } @@ -257,13 +362,13 @@ pub fn validate_eof_code( // Max index can't be zero as it becomes RJUMPI. if max_index == 0 { - return Err(()); + return Err(EofError::RJUMPVZeroMaxIndex); } // +1 is for max_index byte if i + 1 + rjumpv_additional_immediates >= code.len() { // Malfunctional code RJUMPV vtable is not complete - return Err(()); + return Err(EofError::MissingRJUMPVImmediateBytes); } let mut jumps = Vec::with_capacity(max_index); @@ -272,10 +377,9 @@ pub fn validate_eof_code( read_i16(unsafe { code.as_ptr().add(i + 2 + 2 * vtablei) }) as isize; if offset == 0 { // jump immediate instruction is not allowed. - return Err(()); + return Err(EofError::JumpZeroOffset); } - jumps[vtablei] = - offset + i as isize + 2 + rjumpv_additional_immediates as isize; + jumps.push(offset + i as isize + 2 + rjumpv_additional_immediates as isize); } absolute_jumpdest = jumps } @@ -283,12 +387,12 @@ pub fn validate_eof_code( let section_i = read_u16(unsafe { code.as_ptr().add(i + 1) }) as usize; let Some(target_types) = types.get(section_i) else { // code section out of bounds. - return Err(()); + return Err(EofError::CodeSectionOutOfBounds); }; if target_types.outputs == EOF_NON_RETURNING_FUNCTION { // callf to non returning function is not allowed - return Err(()); + return Err(EofError::CALLFNonReturningFunction); } // stack input for this opcode is the input of the called code. stack_requirement = target_types.inputs as i32; @@ -303,7 +407,7 @@ pub fn validate_eof_code( > STACK_LIMIT as i32 { // if stack max items + called code max stack size - return Err(()); + return Err(EofError::StackOverflow); } } opcode::JUMPF => { @@ -311,7 +415,7 @@ pub fn validate_eof_code( // 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(()); + return Err(EofError::CodeSectionOutOfBounds); }; // we decrement types.inputs as they are considered send to the called code. @@ -321,7 +425,7 @@ pub fn validate_eof_code( > STACK_LIMIT as i32 { // stack overflow - return Err(()); + return Err(EofError::StackOverflow); } accessed_codes.insert(target_index); @@ -334,7 +438,7 @@ pub fn validate_eof_code( } else { // check if target code produces enough outputs. if target_types.outputs < this_types.outputs { - return Err(()); + return Err(EofError::JUMPFEnoughOutputs); } // TODO(EOF) stack requirements for this opcode. @@ -342,7 +446,7 @@ pub fn validate_eof_code( // if this instruction max + target_types max is more then stack limit. if this_instruction.biggest + stack_requirement > STACK_LIMIT as i32 { - return Err(()); + return Err(EofError::StackOverflow); } } } @@ -350,14 +454,16 @@ pub fn validate_eof_code( let index = read_u16(unsafe { 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(()); + return Err(EofError::DataLoadOutOfBounds); } } opcode::RETF => { stack_requirement = this_types.outputs as i32; if this_instruction.biggest > stack_requirement { // stack_higher_than_outputs_required - return Err(()); + // TODO(EOF) Why is this here. Why are we erroring if biggest number + // is more than outputs? + return Err(EofError::RETFBiggestStackNumMoreThenOutputs); } } opcode::DUPN => { @@ -375,22 +481,21 @@ pub fn validate_eof_code( } _ => {} } - // 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(()); + return Err(EofError::StackUnderflow); } // 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(()); + return Err(EofError::JumpUnderflow); } if absolute_jump >= code.len() as isize { // jump to out of bounds - return Err(()); + return Err(EofError::JumpOverflow); } // fine to cast as bounds are checked. let absolute_jump = absolute_jump as usize; @@ -398,7 +503,7 @@ pub fn validate_eof_code( let target_jump = &mut jumps[absolute_jump]; if target_jump.is_immediate { // Jump target is immediate byte. - return Err(()); + return Err(EofError::BackwardJumpToImmediateBytes); } // needed to mark forward jumps. It does not do anything for backward jumps. @@ -408,11 +513,11 @@ pub fn validate_eof_code( // backward jumps should have same smallest and biggest stack items. if this_instruction.biggest != target_jump.biggest { // wrong jumpdest. - return Err(()); + return Err(EofError::BackwardJumpBiggestNumMismatch); } if this_instruction.smallest != target_jump.smallest { // wrong jumpdest. - return Err(()); + return Err(EofError::BackwardJumpSmallestNumMismatch); } } else { // forward jumps can make min even smallest size @@ -422,10 +527,13 @@ pub fn validate_eof_code( target_jump.biggest = core::cmp::max(target_jump.biggest, this_instruction.biggest); } } - + //println!("stack_io_diff: {}", stack_io_diff); next_smallest = this_instruction.smallest + stack_io_diff; next_biggest = this_instruction.smallest + stack_io_diff; - + // println!( + // "next_smallest: {} next_biggest: {}", + // next_smallest, next_biggest + // ); // additional immediate are from RJUMPV vtable. i += 1 + opcode.immediate_size as usize + rjumpv_additional_immediates; } @@ -433,7 +541,7 @@ pub fn validate_eof_code( // last opcode should be terminating if !is_after_termination { // wrong termination. - return Err(()); + return Err(EofError::LastInstructionNotTerminating); } // TODO integrate max so we dont need to iterate again @@ -442,28 +550,10 @@ pub fn validate_eof_code( max_stack_requirement = core::cmp::max(opcode.biggest, max_stack_requirement); } + if max_stack_requirement != types[this_types_index].max_stack_size as i32 { + // stack overflow + return Err(EofError::MaxStackMismatch); + } + Ok(accessed_codes) } - -// For secquential opcodes min and max values are same. -// /// Difference is with jumps, -// #[derive(Copy, Clone)] -// struct StackNum { -// /// 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, -// } - -// impl StackNum { -// fn next(&self, diff: i16) -> Self { -// Self { -// smallest: self.smallest + diff as i32, -// biggest: self.biggest + diff as i32, -// } -// } -// fn merge_jumpdest(&mut self, other: Self) { -// self.smallest = core::cmp::min(self.smallest, other.smallest); -// self.biggest = core::cmp::max(self.biggest, other.biggest); -// } -// } 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/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..7684304686 --- /dev/null +++ b/crates/interpreter/tests/eof.rs @@ -0,0 +1,119 @@ +use revm_interpreter::analysis::{validate_raw_eof, EofError}; +use revm_primitives::{Bytes, Eof, HashMap}; +use serde::Deserialize; +use serde_json::Value; +use std::{ + collections::BTreeMap, + path::{Path, PathBuf}, +}; +use walkdir::{DirEntry, WalkDir}; + +// #[test] +// fn eof_run_all_tests() { +// let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests"); +// run_test(&eof_tests) +// } + +#[test] +fn eof_validation_eip3540() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP3540"); + run_test(&eof_tests) +} + +#[test] +fn eof_validation_eip3670() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP3670"); + run_test(&eof_tests) +} + +#[test] +fn eof_validation_eip4200() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP4200"); + run_test(&eof_tests) +} + +#[test] +fn eof_validation_eip4750() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP4750"); + run_test(&eof_tests) +} + +#[test] +fn eof_validation_eip5450() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP5450"); + 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; + let mut types_of_error: HashMap = HashMap::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!( + "Test failed: {} - {}\nresult:{:?}\nrevm result:{:?}\nbytes:{:?}\neof: {eof:?}", + name, vector_name, test_vector.results.prague, res, test_vector.code + ); + *types_of_error + .entry(res.err().unwrap_or(EofError::TEST)) + .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, +} From f219ed66422451fce4b40be7996360c4798fc81e Mon Sep 17 00:00:00 2001 From: rakita Date: Wed, 27 Mar 2024 14:49:26 +0100 Subject: [PATCH 33/54] RETURNDATALOAD, fix call bugs, refactor gas warm/cold calc --- bins/revme/src/cmd/statetest/runner.rs | 4 +- crates/interpreter/src/call_inputs.rs | 18 +++--- crates/interpreter/src/eof_create_inputs.rs | 2 +- crates/interpreter/src/gas/calc.rs | 64 ++++++++++--------- crates/interpreter/src/host.rs | 4 +- .../interpreter/src/instructions/contract.rs | 36 ++++++----- .../src/instructions/contract/call_helpers.rs | 8 +-- .../interpreter/src/instructions/control.rs | 26 ++++---- crates/interpreter/src/instructions/data.rs | 4 +- crates/interpreter/src/instructions/host.rs | 22 ++----- crates/interpreter/src/instructions/opcode.rs | 2 +- crates/interpreter/src/instructions/system.rs | 61 +++++++++++++++++- .../interpreter/src/instructions/utility.rs | 8 +-- crates/interpreter/src/interpreter.rs | 5 +- .../interpreter/src/interpreter/analysis.rs | 13 ++-- crates/interpreter/src/lib.rs | 7 ++ crates/interpreter/tests/eof.rs | 11 ++-- crates/precompile/src/blake2.rs | 2 +- crates/revm/src/inspector/handler_register.rs | 2 +- crates/revm/src/journaled_state.rs | 17 ++--- 20 files changed, 184 insertions(+), 132 deletions(-) diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index e9b0e75956..c29476a839 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -67,7 +67,9 @@ pub fn find_all_json_tests(path: &Path) -> Vec { fn skip_test(path: &Path) -> bool { let path_str = path.to_str().expect("Path is not valid UTF-8"); let name = path.file_name().unwrap().to_str().unwrap(); - + if path_str.contains("stRandom") { + return true; + } matches!( name, // funky test with `bigint 0x00` value in json :) not possible to happen on mainnet and require diff --git a/crates/interpreter/src/call_inputs.rs b/crates/interpreter/src/call_inputs.rs index 83a309baa3..e16459496f 100644 --- a/crates/interpreter/src/call_inputs.rs +++ b/crates/interpreter/src/call_inputs.rs @@ -9,29 +9,29 @@ 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 not return anything. + /// 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, - /// This account bytecode is going to be executed. + /// 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 this call. + /// This caller that is invoking this call. pub caller: Address, - /// Ether value that is transferred. + /// Value is Ether that is transferred. /// - /// If enum is `Value` ether transfer is executed - /// between `caller`` and the `target_address`. + /// If enum is [`TransferValue::Value`] balance is transferer from `caller` to the `target_address`. /// - /// If enum is `ApparentValue` transfer is not done and apparent value is - /// used by CALLVALUE opcode. This is needed for delegate call. + /// If enum is [`TransferValue::ApparentValue`] balance transfer + /// is **not** done and apparent value is used by CALLVALUE opcode. + /// This is used by delegate call. pub value: TransferValue, /// The scheme used for the call. pub scheme: CallScheme, /// Whether this is a static call. pub is_static: bool, - /// Is called from EOF code. + /// Call is initiated from EOF bytecode. pub is_eof: bool, } diff --git a/crates/interpreter/src/eof_create_inputs.rs b/crates/interpreter/src/eof_create_inputs.rs index f5e5cecda0..875b3bce08 100644 --- a/crates/interpreter/src/eof_create_inputs.rs +++ b/crates/interpreter/src/eof_create_inputs.rs @@ -15,7 +15,7 @@ pub struct EOFCreateInput { /// Gas limit for the create call. pub gas_limit: u64, /// Return memory range. If EOF creation Reverts it can return the - /// the memmory range. + /// the memory range. pub return_memory_range: Range, } diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index f0a904f675..c1396e2e67 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -108,11 +108,7 @@ pub fn extcodecopy_cost(len: u64, is_cold: bool) -> Option { let wordr = len % 32; let base_gas: u64 = if SPEC::enabled(BERLIN) { - if is_cold { - COLD_ACCOUNT_ACCESS_COST - } else { - WARM_STORAGE_READ_COST - } + warm_cold_cost(is_cold) } else if SPEC::enabled(TANGERINE) { 700 } else { @@ -124,11 +120,7 @@ pub fn extcodecopy_cost(len: u64, is_cold: bool) -> Option { #[inline] pub fn account_access_gas(is_cold: bool) -> u64 { if SPEC::enabled(BERLIN) { - if is_cold { - COLD_ACCOUNT_ACCESS_COST - } else { - WARM_STORAGE_READ_COST - } + warm_cold_cost(is_cold) } else if SPEC::enabled(ISTANBUL) { 700 } else { @@ -218,7 +210,7 @@ pub fn sstore_cost( } /// EIP-2200: Structured Definitions for Net Gas Metering -#[inline(always)] +#[inline] fn istanbul_sstore_cost( original: U256, current: U256, @@ -236,7 +228,7 @@ fn istanbul_sstore_cost( } /// Frontier sstore cost just had two cases set and reset values -#[inline(always)] +#[inline] fn frontier_sstore_cost(current: U256, new: U256) -> u64 { if current == U256::ZERO && new != U256::ZERO { SSTORE_SET @@ -271,15 +263,22 @@ pub fn selfdestruct_cost(res: SelfDestructResult) -> u64 { gas } +/// Calculate call gas cost for the call instruction. +/// +/// There is three types of gas. +/// 1. Account access gas. after berlin it can be cold or warm. +/// 2. Transfer value gas. If value is transferred and balance of target account is updated. +/// 3. If account is not existing and needs to be created. After Spurious dragon +/// this is only accounted if value is transferred. #[inline] -pub fn call_cost(transfers_value: bool, is_new: bool, is_cold: bool) -> u64 { +pub fn call_cost( + transfers_value: bool, + is_cold: bool, + new_account_accounting: bool, +) -> u64 { // Account access. let mut gas = if SPEC::enabled(BERLIN) { - if is_cold { - COLD_ACCOUNT_ACCESS_COST - } else { - WARM_STORAGE_READ_COST - } + warm_cold_cost(is_cold) } else if SPEC::enabled(TANGERINE) { // EIP-150: Gas cost changes for IO-heavy operations 700 @@ -292,30 +291,33 @@ pub fn call_cost(transfers_value: bool, is_new: bool, is_cold: bool) gas += CALLVALUE; } - // new account cost; - // EIP-161: State trie clearing (invariant-preserving alternative) - if is_new || (SPEC::enabled(SPURIOUS_DRAGON) && transfers_value) { - gas += NEWACCOUNT; + // new account cost + if new_account_accounting { + // EIP-161: State trie clearing (invariant-preserving alternative) + if SPEC::enabled(SPURIOUS_DRAGON) { + // account only if there is value transferred. + if transfers_value { + gas += NEWACCOUNT; + } + } else { + gas += NEWACCOUNT; + } } gas } #[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 - } +pub const fn warm_cold_cost(is_cold: bool) -> u64 { + if is_cold { + COLD_ACCOUNT_ACCESS_COST } else { - regular_value + WARM_STORAGE_READ_COST } } #[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) diff --git a/crates/interpreter/src/host.rs b/crates/interpreter/src/host.rs index 2c0802afbd..566987fea1 100644 --- a/crates/interpreter/src/host.rs +++ b/crates/interpreter/src/host.rs @@ -67,8 +67,8 @@ pub struct SStoreResult { pub struct LoadAccountResult { /// Is account cold loaded pub is_cold: bool, - /// Is account new - pub is_not_existing: bool, + /// Is account empty, if true account is not created. + pub is_empty: bool, } /// Result of a call that resulted in a self destruct. diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 6b552c765b..2277e775a9 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -10,7 +10,7 @@ use crate::{ interpreter::{Interpreter, InterpreterAction}, primitives::{Address, Bytes, Eof, Spec, SpecId::*, B256, U256}, CallInputs, CallScheme, CreateInputs, CreateScheme, EOFCreateInput, Host, InstructionResult, - TransferValue, MAX_INITCODE_SIZE, + LoadAccountResult, TransferValue, MAX_INITCODE_SIZE, }; use core::{cmp::max, ops::Range}; use std::boxed::Box; @@ -188,8 +188,9 @@ pub fn extcall_gas_calc( gas!(interpreter, gas::COLD_ACCOUNT_ACCESS_COST, None); } - let is_new = !load_result.is_not_existing; - let call_cost = gas::call_cost::(transfers_value, is_new, load_result.is_cold); + // TODO(EOF) is_empty should only be checked on delegatecall + let call_cost = + gas::call_cost::(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 @@ -387,7 +388,8 @@ pub fn call(interpreter: &mut Interpreter, host: &mut H) { let local_gas_limit = u64::try_from(local_gas_limit).unwrap_or(u64::MAX); pop!(interpreter, value); - if interpreter.is_static && value != U256::ZERO { + let has_transfer = value != U256::ZERO; + if interpreter.is_static && has_transfer { interpreter.instruction_result = InstructionResult::CallNotAllowedInsideStatic; return; } @@ -396,15 +398,15 @@ pub fn call(interpreter: &mut Interpreter, host: &mut H) { return; }; - let Some(load_result) = host.load_account(to) else { + 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, - load_result, - value != U256::ZERO, + is_cold, + has_transfer, + is_empty, local_gas_limit, ) else { return; @@ -413,7 +415,7 @@ pub fn call(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas_limit); // add call stipend if there is value to be transferred. - if value != U256::ZERO { + if has_transfer { gas_limit = gas_limit.saturating_add(gas::CALL_STIPEND); } @@ -447,15 +449,16 @@ pub fn call_code(interpreter: &mut Interpreter, host: &mut return; }; - let Some(load_result) = host.load_account(to) else { + 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, - load_result, + is_cold, value != U256::ZERO, + false, local_gas_limit, ) else { return; @@ -476,7 +479,7 @@ pub fn call_code(interpreter: &mut Interpreter, host: &mut target_address: interpreter.contract.target_address, caller: interpreter.contract.target_address, bytecode_address: to, - value: TransferValue::ApparentValue(value), + value: TransferValue::Value(value), scheme: CallScheme::CallCode, is_static: interpreter.is_static, is_eof: false, @@ -498,13 +501,12 @@ pub fn delegate_call(interpreter: &mut Interpreter, host: & return; }; - let Some(load_result) = host.load_account(to) else { + let Some(LoadAccountResult { is_cold, .. }) = host.load_account(to) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; - let Some(gas_limit) = - calc_call_gas::(interpreter, load_result, false, local_gas_limit) + calc_call_gas::(interpreter, is_cold, false, false, local_gas_limit) else { return; }; @@ -541,13 +543,13 @@ pub fn static_call(interpreter: &mut Interpreter, host: &mu return; }; - let Some(load_result) = host.load_account(to) else { + let Some(LoadAccountResult { is_cold, .. }) = host.load_account(to) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; let Some(gas_limit) = - calc_call_gas::(interpreter, load_result, false, local_gas_limit) + calc_call_gas::(interpreter, is_cold, false, false, local_gas_limit) else { return; }; diff --git a/crates/interpreter/src/instructions/contract/call_helpers.rs b/crates/interpreter/src/instructions/contract/call_helpers.rs index f94a1ad7ed..4d0e49617f 100644 --- a/crates/interpreter/src/instructions/contract/call_helpers.rs +++ b/crates/interpreter/src/instructions/contract/call_helpers.rs @@ -4,7 +4,7 @@ use crate::{ gas, interpreter::Interpreter, primitives::{Bytes, Spec, SpecId::*}, - Host, InstructionResult, LoadAccountResult, + Host, }; use core::{cmp::min, ops::Range}; @@ -47,12 +47,12 @@ pub fn resize_memory_and_return_range( #[inline] pub fn calc_call_gas( interpreter: &mut Interpreter, - load_result: LoadAccountResult, + is_cold: bool, has_transfer: bool, + new_account_accounting: bool, local_gas_limit: u64, ) -> Option { - let is_new = !load_result.is_not_existing; - let call_cost = gas::call_cost::(has_transfer, is_new, load_result.is_cold); + let call_cost = gas::call_cost::(has_transfer, is_cold, new_account_accounting); gas!(interpreter, call_cost, None); diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index a9dd26b15a..38a04be140 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -8,7 +8,7 @@ use crate::{ pub fn rjump(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::BASE); - let offset = read_i16(interpreter.instruction_pointer) as isize; + 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) }; @@ -22,7 +22,7 @@ pub fn rjumpi(interpreter: &mut Interpreter, _host: &mut H) { // `Interpreter::step` so for revm is +2. let mut offset = 2; if !condition.is_zero() { - offset += read_i16(interpreter.instruction_pointer) as isize; + offset += unsafe { read_i16(interpreter.instruction_pointer) } as isize; } interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset) }; @@ -40,12 +40,14 @@ pub fn rjumpv(interpreter: &mut Interpreter, _host: &mut H) { let mut offset = (max_index + 1) * 2 + 1; if case <= max_index { - offset += read_i16(unsafe { - interpreter - .instruction_pointer - // offset for max_index that is one byte - .offset(1 + case * 2) - }) as isize; + 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) }; @@ -67,7 +69,7 @@ pub fn jumpi(interpreter: &mut Interpreter, _host: &mut H) { } } -#[inline(always)] +#[inline] 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) { @@ -87,7 +89,7 @@ pub fn callf(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::LOW); - let idx = read_u16(interpreter.instruction_pointer) as usize; + let idx = unsafe { read_u16(interpreter.instruction_pointer) } as usize; // TODO Check stack with EOF types. if interpreter.function_stack.return_stack_len() == 1024 { @@ -119,7 +121,7 @@ pub fn jumpf(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::LOW); - let idx = read_u16(interpreter.instruction_pointer) as usize; + let idx = unsafe { read_u16(interpreter.instruction_pointer) } as usize; // TODO(EOF) do types stack checks @@ -134,7 +136,7 @@ pub fn pc(interpreter: &mut Interpreter, _host: &mut H) { 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); diff --git a/crates/interpreter/src/instructions/data.rs b/crates/interpreter/src/instructions/data.rs index af51612ad2..806ca8dea6 100644 --- a/crates/interpreter/src/instructions/data.rs +++ b/crates/interpreter/src/instructions/data.rs @@ -3,7 +3,7 @@ use crate::{ instructions::utility::read_u16, interpreter::Interpreter, primitives::U256, - Host, InstructionResult, + Host, }; pub fn data_load(interpreter: &mut Interpreter, _host: &mut H) { @@ -29,7 +29,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); gas!(interpreter, VERYLOW); - let offset = read_u16(interpreter.instruction_pointer) as usize; + let offset = unsafe { read_u16(interpreter.instruction_pointer) } as usize; let slice = interpreter .contract diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index bf1f89e314..cf7825b4bd 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -1,7 +1,7 @@ use crate::{ - gas::{self, COLD_ACCOUNT_ACCESS_COST, WARM_STORAGE_READ_COST}, + gas::{self, warm_cold_cost}, interpreter::Interpreter, - primitives::{Address, Bytes, Log, LogData, Spec, SpecId::*, B256, U256}, + primitives::{Bytes, Log, LogData, Spec, SpecId::*, B256, U256}, Host, InstructionResult, SStoreResult, }; use core::cmp::min; @@ -47,14 +47,7 @@ pub fn extcodesize(interpreter: &mut Interpreter, host: &mu 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 { @@ -74,14 +67,7 @@ pub fn extcodehash(interpreter: &mut Interpreter, host: &mu 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 { diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index 7378499f0b..dac856b674 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -628,7 +628,7 @@ opcodes! { 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<0, 0>; // TODO(EOF) impl + 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; diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index abd2df2aac..8dbad051df 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -120,8 +120,8 @@ pub fn returndatacopy(interpreter: &mut Interpreter, _host: 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; } @@ -135,8 +135,19 @@ pub fn returndatacopy(interpreter: &mut Interpreter, _host: } } +/// Part of EOF https://eips.ethereum.org/EIPS/eip-7069 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) { @@ -144,3 +155,49 @@ 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 index eb7909e9a6..55b1212771 100644 --- a/crates/interpreter/src/instructions/utility.rs +++ b/crates/interpreter/src/instructions/utility.rs @@ -1,7 +1,7 @@ -pub(crate) fn read_i16(ptr: *const u8) -> i16 { - unsafe { i16::from_be_bytes(core::slice::from_raw_parts(ptr, 2).try_into().unwrap()) } +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) fn read_u16(ptr: *const u8) -> u16 { - unsafe { u16::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 d22b0d16a1..7f8b474349 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -317,12 +317,11 @@ impl Interpreter { call_outcome: CallOutcome, ) { self.instruction_result = InstructionResult::Continue; + self.return_data_buffer = call_outcome.output().to_owned(); + let out_offset = call_outcome.memory_start(); let out_len = call_outcome.memory_length(); - - self.return_data_buffer = call_outcome.output().to_owned(); let target_len = min(out_len, self.return_data_buffer.len()); - match call_outcome.instruction_result() { return_ok!() => { // return unspend gas. diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 01ed5eb97a..ca00964d8a 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -9,7 +9,7 @@ use crate::{ legacy::JumpTable, Bytecode, Bytes, Eof, LegacyAnalyzedBytecode, }, - OpCode, OPCODE_INFO_JUMPTABLE, STACK_LIMIT, + OPCODE_INFO_JUMPTABLE, STACK_LIMIT, }; use std::{sync::Arc, vec, vec::Vec}; @@ -233,7 +233,6 @@ e200 */ - /// Validates that: /// * All instructions are valid. /// * It ends with a terminating instruction or RJUMP. @@ -347,7 +346,7 @@ pub fn validate_eof_code( let mut absolute_jumpdest = vec![]; match op { opcode::RJUMP | opcode::RJUMPI => { - let offset = read_i16(unsafe { code.as_ptr().add(i + 1) }) as isize; + let offset = unsafe { read_i16(code.as_ptr().add(i + 1)) } as isize; if offset == 0 { // jump immediate instruction is not allowed. return Err(EofError::JumpToImmediateBytes); @@ -374,7 +373,7 @@ pub fn validate_eof_code( let mut jumps = Vec::with_capacity(max_index); for vtablei in 0..max_index { let offset = - read_i16(unsafe { code.as_ptr().add(i + 2 + 2 * vtablei) }) as isize; + unsafe { read_i16(code.as_ptr().add(i + 2 + 2 * vtablei)) } as isize; if offset == 0 { // jump immediate instruction is not allowed. return Err(EofError::JumpZeroOffset); @@ -384,7 +383,7 @@ pub fn validate_eof_code( absolute_jumpdest = jumps } opcode::CALLF => { - let section_i = read_u16(unsafe { code.as_ptr().add(i + 1) }) as usize; + 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(EofError::CodeSectionOutOfBounds); @@ -411,7 +410,7 @@ pub fn validate_eof_code( } } opcode::JUMPF => { - let target_index = read_u16(unsafe { code.as_ptr().add(i + 1) }) as usize; + 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. @@ -451,7 +450,7 @@ pub fn validate_eof_code( } } opcode::DATALOADN => { - let index = read_u16(unsafe { code.as_ptr().add(i + 1) }) as isize; + 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(EofError::DataLoadOutOfBounds); diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index 86c1bfb14d..621c88ea37 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -12,6 +12,13 @@ extern crate alloc as std; #[macro_use] mod macros; +// silence lint +#[cfg(test)] +use serde_json as _; + +#[cfg(test)] +use walkdir as _; + mod call_inputs; mod call_outcome; mod create_inputs; diff --git a/crates/interpreter/tests/eof.rs b/crates/interpreter/tests/eof.rs index 7684304686..cb8481e24d 100644 --- a/crates/interpreter/tests/eof.rs +++ b/crates/interpreter/tests/eof.rs @@ -1,18 +1,17 @@ use revm_interpreter::analysis::{validate_raw_eof, EofError}; use revm_primitives::{Bytes, Eof, HashMap}; use serde::Deserialize; -use serde_json::Value; use std::{ collections::BTreeMap, path::{Path, PathBuf}, }; use walkdir::{DirEntry, WalkDir}; -// #[test] -// fn eof_run_all_tests() { -// let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests"); -// run_test(&eof_tests) -// } +#[test] +fn eof_run_all_tests() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests"); + run_test(&eof_tests) +} #[test] fn eof_validation_eip3540() { diff --git a/crates/precompile/src/blake2.rs b/crates/precompile/src/blake2.rs index 6a173494e9..0614ece5a8 100644 --- a/crates/precompile/src/blake2.rs +++ b/crates/precompile/src/blake2.rs @@ -81,7 +81,7 @@ mod algo { 0x5be0cd19137e2179, ]; - #[inline(always)] + #[inline] #[allow(clippy::many_single_char_names)] /// G function: fn g(v: &mut [u64], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { diff --git a/crates/revm/src/inspector/handler_register.rs b/crates/revm/src/inspector/handler_register.rs index 872623436f..f0772883c3 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 } diff --git a/crates/revm/src/journaled_state.rs b/crates/revm/src/journaled_state.rs index 3ce1a6b3a5..a5eee7e20c 100644 --- a/crates/revm/src/journaled_state.rs +++ b/crates/revm/src/journaled_state.rs @@ -509,7 +509,7 @@ impl JournaledState { Ok(SelfDestructResult { had_value: balance != U256::ZERO, is_cold: load_result.is_cold, - target_exists: !load_result.is_not_existing, + target_exists: !load_result.is_empty, previously_destroyed, }) } @@ -586,18 +586,15 @@ impl JournaledState { 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(LoadAccountResult { - is_not_existing: !exist, - is_cold, - }) + Ok(LoadAccountResult { is_empty, is_cold }) } /// Loads code. From 8a4d9a21364736107d879bebed79c1f732c166b7 Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 28 Mar 2024 13:45:45 +0100 Subject: [PATCH 34/54] debug session, rjumpv imm fix --- bins/revme/src/cmd/eof.rs | 18 +++ crates/interpreter/src/instructions.rs | 3 - .../interpreter/src/instructions/contract.rs | 6 +- crates/interpreter/src/interpreter.rs | 2 +- .../interpreter/src/interpreter/analysis.rs | 132 ++++++++---------- .../interpreter/src/interpreter/contract.rs | 2 +- crates/interpreter/src/lib.rs | 4 +- .../src/{instructions => }/opcode.rs | 7 +- crates/interpreter/src/opcode/eof_printer.rs | 72 ++++++++++ crates/interpreter/tests/eof.rs | 21 +++ crates/primitives/src/bytecode.rs | 7 +- crates/primitives/src/bytecode/eof.rs | 4 +- crates/primitives/src/bytecode/eof/body.rs | 2 +- crates/primitives/src/bytecode/eof/header.rs | 8 +- .../src/bytecode/eof/types_section.rs | 7 +- crates/revm/src/context/evm_context.rs | 8 +- 16 files changed, 195 insertions(+), 108 deletions(-) create mode 100644 bins/revme/src/cmd/eof.rs rename crates/interpreter/src/{instructions => }/opcode.rs (99%) create mode 100644 crates/interpreter/src/opcode/eof_printer.rs diff --git a/bins/revme/src/cmd/eof.rs b/bins/revme/src/cmd/eof.rs new file mode 100644 index 0000000000..75441ff058 --- /dev/null +++ b/bins/revme/src/cmd/eof.rs @@ -0,0 +1,18 @@ +use std::path::PathBuf; +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: Vec, +} + +impl Cmd { + /// Run statetest command. + pub fn run(&self) -> Result<(), TestError> { + + } +} diff --git a/crates/interpreter/src/instructions.rs b/crates/interpreter/src/instructions.rs index 0de794092a..7f11f93f4d 100644 --- a/crates/interpreter/src/instructions.rs +++ b/crates/interpreter/src/instructions.rs @@ -11,9 +11,6 @@ pub mod host; pub mod host_env; pub mod i256; pub mod memory; -pub mod opcode; pub mod stack; pub mod system; pub mod utility; - -pub use opcode::{Instruction, OpCode, OPCODE_INFO_JUMPTABLE}; diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 2277e775a9..47061ca644 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -233,7 +233,7 @@ pub fn extcall(interpreter: &mut Interpreter, host: &mut H) inputs: Box::new(CallInputs { input, gas_limit, - target_address: target_address, + target_address, caller: interpreter.contract.target_address, bytecode_address: target_address, value: TransferValue::Value(value), @@ -265,7 +265,7 @@ pub fn extdcall(interpreter: &mut Interpreter, host: &mut H inputs: Box::new(CallInputs { input, gas_limit, - target_address: target_address, + target_address, caller: interpreter.contract.target_address, bytecode_address: target_address, value: TransferValue::ApparentValue(interpreter.contract.call_value), @@ -297,7 +297,7 @@ pub fn extscall(interpreter: &mut Interpreter, host: &mut H) { inputs: Box::new(CallInputs { input, gas_limit, - target_address: target_address, + target_address, caller: interpreter.contract.target_address, bytecode_address: target_address, value: TransferValue::Value(U256::ZERO), diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 56a3e47280..e4ecf2acb4 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -199,7 +199,7 @@ impl Interpreter { panic!("Code not found") }; self.bytecode = code.clone(); - self.instruction_pointer = unsafe { self.bytecode.as_ptr().offset(pc as isize) }; + self.instruction_pointer = unsafe { self.bytecode.as_ptr().add(pc) }; } /// Inserts the output of a `create` call into the interpreter. diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index ca00964d8a..89efcaddd7 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -110,7 +110,7 @@ pub fn validate_eof_codes(eof: &Eof) -> Result<(), EofError> { while let Some(index) = queue.pop() { let code = &eof.body.code_section[index]; let accessed_codes = validate_eof_code( - &code, + code, eof.header.data_size as usize, index, &eof.body.types_section, @@ -125,7 +125,7 @@ pub fn validate_eof_codes(eof: &Eof) -> Result<(), EofError> { }); } // iterate over accessed codes and check if all are accessed. - if queued_codes.into_iter().find(|&x| x == false).is_some() { + if queued_codes.into_iter().any(|x| !x) { return Err(EofError::CodeSectionNotAccessed); } @@ -134,37 +134,7 @@ pub fn validate_eof_codes(eof: &Eof) -> Result<(), EofError> { /* -//0x6001800100 -0x6001 PUSH1 -80 DUP1 -01 ADD -00 STOP - -// 0xef0001010004020001000504000000008000026001800100 -0xef00 magic -01 version -01 kind -0004 04 size -02 kind -0001 num of codes -0005 size of code -04 kind data -0000 size of data -00 terminator -00 inputs -80 non returning fn -0002 max stack elements -6001800100 - -0x6001 PUSH0 -80 -80 -80 -80 -80 -80 -f1 -00 +0x6000e2010005000c6001e0000d60026003e0000660036004600500 */ @@ -225,14 +195,6 @@ pub enum EofError { MaxStackMismatch, } -/* -0x6000 PUSH1 -e200 -00035b5b00600160015500 - - - */ - /// Validates that: /// * All instructions are valid. /// * It ends with a terminating instruction or RJUMP. @@ -271,6 +233,18 @@ pub fn validate_eof_code( biggest: i32, } + impl InstructionInfo { + #[inline] + fn mark_as_immediate(&mut self) -> Result<(), EofError> { + if self.is_jumpdest { + // Jump to immediate bytes. + return Err(EofError::JumpToImmediateBytes); + } + self.is_immediate = true; + Ok(()) + } + } + impl Default for InstructionInfo { fn default() -> Self { Self { @@ -294,11 +268,6 @@ pub fn validate_eof_code( while i < code.len() { let op = code[i]; let opcode = &OPCODE_INFO_JUMPTABLE[op as usize]; - let this_instruction = &mut jumps[i]; - 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; let Some(opcode) = opcode else { // err unknown opcode. @@ -310,8 +279,18 @@ pub fn validate_eof_code( return Err(EofError::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 { + if is_after_termination && !this_instruction.is_jumpdest { // opcode after termination was not accessed. return Err(EofError::InstructionNotForwardAccessed); } @@ -328,12 +307,7 @@ pub fn validate_eof_code( // mark immediate bytes as non-jumpable. for imm in 1..opcode.immediate_size as usize + 1 { // SAFETY: immediate size is checked above. - let jumptable = &mut jumps[i + imm]; - if jumptable.is_jumpdest { - // There is a jump to the immediate bytes. - return Err(EofError::JumpToImmediateBytes); - } - jumptable.is_immediate = true; + jumps[i + imm].mark_as_immediate()?; } } // IO diff used to generate next instruction smallest/biggest value. @@ -347,22 +321,26 @@ pub fn validate_eof_code( match op { opcode::RJUMP | opcode::RJUMPI => { let offset = unsafe { read_i16(code.as_ptr().add(i + 1)) } as isize; - if offset == 0 { - // jump immediate instruction is not allowed. - return Err(EofError::JumpToImmediateBytes); - } - absolute_jumpdest = vec![offset + 3 + i as isize] + // TODO(EOF) temporarily disabled for tests + // if offset == 0 { + // // jump immediate instruction is not allowed. + // return Err(EofError::JumpToImmediateBytes); + // } + 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 = (1 + max_index) * 2; + rjumpv_additional_immediates = len * 2; // Max index can't be zero as it becomes RJUMPI. - if max_index == 0 { - return Err(EofError::RJUMPVZeroMaxIndex); - } + // TODO(EOF) temporarily disabled this + // if max_index == 0 { + // return Err(EofError::RJUMPVZeroMaxIndex); + // } // +1 is for max_index byte if i + 1 + rjumpv_additional_immediates >= code.len() { @@ -370,14 +348,21 @@ pub fn validate_eof_code( return Err(EofError::MissingRJUMPVImmediateBytes); } - let mut jumps = Vec::with_capacity(max_index); - for vtablei in 0..max_index { + // 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; - if offset == 0 { - // jump immediate instruction is not allowed. - return Err(EofError::JumpZeroOffset); - } + // TODO(EOF) temporarily disabled for tests + // if offset == 0 { + // // jump immediate instruction is not allowed. + // return Err(EofError::JumpZeroOffset); + // } jumps.push(offset + i as isize + 2 + rjumpv_additional_immediates as isize); } absolute_jumpdest = jumps @@ -396,7 +381,7 @@ pub fn validate_eof_code( // 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() as i32; + stack_io_diff = target_types.io_diff(); // mark called code as accessed. accessed_codes.insert(section_i); @@ -441,7 +426,7 @@ pub fn validate_eof_code( } // TODO(EOF) stack requirements for this opcode. - stack_requirement = (target_types.outputs as i32 + this_types.io_diff()) as i32; + stack_requirement = target_types.outputs as i32 + this_types.io_diff(); // if this instruction max + target_types max is more then stack limit. if this_instruction.biggest + stack_requirement > STACK_LIMIT as i32 { @@ -528,11 +513,8 @@ pub fn validate_eof_code( } //println!("stack_io_diff: {}", stack_io_diff); next_smallest = this_instruction.smallest + stack_io_diff; - next_biggest = this_instruction.smallest + stack_io_diff; - // println!( - // "next_smallest: {} next_biggest: {}", - // next_smallest, next_biggest - // ); + next_biggest = this_instruction.biggest + stack_io_diff; + // additional immediate are from RJUMPV vtable. i += 1 + opcode.immediate_size as usize + rjumpv_additional_immediates; } diff --git a/crates/interpreter/src/interpreter/contract.rs b/crates/interpreter/src/interpreter/contract.rs index 94620f01b8..966dd2051b 100644 --- a/crates/interpreter/src/interpreter/contract.rs +++ b/crates/interpreter/src/interpreter/contract.rs @@ -33,7 +33,7 @@ impl Contract { caller: Address, call_value: U256, ) -> Self { - let bytecode = to_analysed(bytecode).try_into().expect("it is analyzed"); + let bytecode = to_analysed(bytecode); Self { input, diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index 621c88ea37..e0dbb6f6e3 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -31,6 +31,7 @@ mod host; mod instruction_result; pub mod instructions; pub mod interpreter; +pub mod opcode; // Reexport primary types. pub use call_inputs::{CallInputs, CallScheme, TransferValue}; @@ -43,7 +44,8 @@ pub use function_stack::{FunctionReturnFrame, FunctionStack}; pub use gas::Gas; pub use host::{DummyHost, Host, LoadAccountResult, SStoreResult, SelfDestructResult}; pub use instruction_result::*; -pub use instructions::{opcode, Instruction, OpCode, OPCODE_INFO_JUMPTABLE}; +pub use opcode::{Instruction, OpCode, OPCODE_INFO_JUMPTABLE}; + pub use interpreter::{ analysis, next_multiple_of_32, Contract, Interpreter, InterpreterAction, InterpreterResult, SharedMemory, Stack, EMPTY_SHARED_MEMORY, STACK_LIMIT, diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/opcode.rs similarity index 99% rename from crates/interpreter/src/instructions/opcode.rs rename to crates/interpreter/src/opcode.rs index dac856b674..89aafe9d33 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -1,7 +1,8 @@ //! EVM opcode definitions and utilities. -use super::*; -use crate::{primitives::Spec, Host, Interpreter}; +pub mod eof_printer; + +use crate::{instructions::*, primitives::Spec, Host, Interpreter}; use core::fmt; use std::boxed::Box; @@ -605,7 +606,7 @@ opcodes! { // 0xDD // 0xDE // 0xDF - 0xE0 => RJUMP => control::rjump => stack_io<0, 0>, imm_size<2>; + 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>; diff --git a/crates/interpreter/src/opcode/eof_printer.rs b/crates/interpreter/src/opcode/eof_printer.rs new file mode 100644 index 0000000000..274d280e57 --- /dev/null +++ b/crates/interpreter/src/opcode/eof_printer.rs @@ -0,0 +1,72 @@ +use revm_primitives::hex; + +use self::utility::read_i16; + +use super::*; + +pub fn print_eof_code(code: &[u8]) { + // We can check validity and jump destinations in one pass. + let mut i = 0; + let mut rjumpv_additional_immediates = 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); + 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]) + ); + } + println!(""); + + 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; + if offset == 0 { + println!("Malformed code: zero offset in RJUMPV"); + } + + println!("RJUMPV[{vtablei}]: 0x{offset:04X}({offset})"); + } + } + + i += 1 + opcode.immediate_size as usize + rjumpv_additional_immediates; + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn sanity_test() { + print_eof_code(&hex!("6001e200ffff00")); + } +} diff --git a/crates/interpreter/tests/eof.rs b/crates/interpreter/tests/eof.rs index cb8481e24d..f313e4667a 100644 --- a/crates/interpreter/tests/eof.rs +++ b/crates/interpreter/tests/eof.rs @@ -7,6 +7,23 @@ use std::{ }; use walkdir::{DirEntry, WalkDir}; +// EOF_InvalidTypeSectionSize +// EOF_InvalidJumpDestination + +/* +result:Result { result: false, exception: Some("EOF_InvalidJumpDestination") } +revm result:Ok(Eof { header: EofHeader { types_size: 4, code_sizes: [7], container_sizes: [], data_size: 0, sum_code_sizes: 7, sum_container_sizes: 0 }, body: EofBody { types_section: [TypesSection { inputs: 0, outputs: 128, max_stack_size: 1 }], +code_section: [0x6001e200ffff00], container_section: [], data_section: 0x, is_data_filled: true }, raw: Some(0xef0001010004020001000704000000008000016001e200ffff00) }) + + +result:Result { result: false, exception: Some("EOF_InvalidTypeSectionSize") } +revm result:Ok(Eof { header: EofHeader { types_size: 8, code_sizes: [3], container_sizes: [], data_size: 4, sum_code_sizes: 3, sum_container_sizes: 0 }, body: EofBody { types_section: [TypesSection { inputs: 0, outputs: 128, max_stack_size: 1 }, TypesSection { inputs: 0, outputs: 0, max_stack_size: 0 }], +code_section: [0x305000], container_section: [], data_section: 0x0bad60a7, is_data_filled: true }, raw: Some(0xef000101000802000100030400040000800001000000003050000bad60a7) }) +bytes:0xef000101000802000100030400040000800001000000003050000bad60a7 + + +*/ + #[test] fn eof_run_all_tests() { let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests"); @@ -19,24 +36,28 @@ fn eof_validation_eip3540() { run_test(&eof_tests) } +// One MaxStackMismatch #[test] fn eof_validation_eip3670() { let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP3670"); run_test(&eof_tests) } +// BIG CODE 5b5b5b5b.. #[test] fn eof_validation_eip4200() { let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP4200"); run_test(&eof_tests) } +// EOF_InvalidFirstSectionType #[test] fn eof_validation_eip4750() { let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP4750"); run_test(&eof_tests) } +// #[test] fn eof_validation_eip5450() { let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP5450"); diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index 72d43deecf..7989b851c2 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -105,10 +105,7 @@ impl Bytecode { /// Returns false if bytecode can't be executed in Interpreter. pub fn is_execution_ready(&self) -> bool { - match self { - Self::LegacyRaw(_) => false, - _ => true, - } + !matches!(self, Self::LegacyRaw(_)) } /// Returns a reference to the original bytecode. @@ -127,7 +124,7 @@ impl Bytecode { match self { Self::LegacyRaw(bytes) => bytes.len(), Self::LegacyAnalyzed(analyzed) => analyzed.original_len(), - Self::Eof(eof) => eof.len(), + Self::Eof(eof) => eof.size(), } } diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index dcd2bc81c5..16d77505d2 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -27,8 +27,8 @@ impl Default for Eof { impl Eof { /// Returns len of the header and body in bytes. - pub fn len(&self) -> usize { - self.header.len() + self.header.body_len() + pub fn size(&self) -> usize { + self.header.size() + self.header.body_size() } pub fn raw(&self) -> Option { diff --git a/crates/primitives/src/bytecode/eof/body.rs b/crates/primitives/src/bytecode/eof/body.rs index cbc693ffba..e0e8180ab3 100644 --- a/crates/primitives/src/bytecode/eof/body.rs +++ b/crates/primitives/src/bytecode/eof/body.rs @@ -19,7 +19,7 @@ impl EofBody { } pub fn decode(input: &Bytes, header: &EofHeader) -> Result { - let header_len = header.len(); + 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; diff --git a/crates/primitives/src/bytecode/eof/header.rs b/crates/primitives/src/bytecode/eof/header.rs index a6fc1773b4..e469cc6e4b 100644 --- a/crates/primitives/src/bytecode/eof/header.rs +++ b/crates/primitives/src/bytecode/eof/header.rs @@ -71,7 +71,7 @@ impl EofHeader { /// terminator 1 byte /// /// It is minimum 15 bytes (there is at least one code section). - pub fn len(&self) -> usize { + pub fn size(&self) -> usize { let optional_container_sizes = if self.container_sizes.is_empty() { 0 } else { @@ -84,12 +84,12 @@ impl EofHeader { self.types_size as usize / 4 } - pub fn body_len(&self) -> usize { + pub fn body_size(&self) -> usize { self.sum_code_sizes + self.sum_container_sizes + self.data_size as usize } - pub fn eof_len(&self) -> usize { - self.len() + self.body_len() + pub fn eof_size(&self) -> usize { + self.size() + self.body_size() } pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), ()> { diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs index 3dae1a6984..8225f7f204 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -4,12 +4,13 @@ use super::decode_helpers::{consume_u16, consume_u8}; #[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 + /// inputs - 1 byte - `0x00-0x7F` + /// number of stack elements the code section consumes pub inputs: u8, - /// outputs 1 byte 0x00-0x80 + /// 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 + /// 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, } diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index bbde00548b..84b1c4ff13 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -205,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, - Some(code_hash), - &inputs, - ); + 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(), From 54d3d238848994ed1e451f045064950f6d2188ab Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 31 Mar 2024 04:00:31 +0200 Subject: [PATCH 35/54] fixing validation bugs, bytecode decoder for EOF in revme --- bins/revm-test/Cargo.toml | 2 +- bins/revme/src/cmd.rs | 7 + bins/revme/src/cmd/bytecode.rs | 39 + bins/revme/src/cmd/eof.rs | 18 - crates/interpreter/src/instructions/i256.rs | 7 +- .../interpreter/src/interpreter/analysis.rs | 177 +- crates/interpreter/src/opcode.rs | 84 +- crates/interpreter/src/opcode/eof_printer.rs | 16 +- .../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 + crates/interpreter/tests/eof.rs | 118 +- crates/primitives/src/bytecode/eof.rs | 35 +- crates/primitives/src/bytecode/eof/body.rs | 8 +- .../src/bytecode/eof/decode_helpers.rs | 10 +- crates/primitives/src/bytecode/eof/header.rs | 44 +- .../src/bytecode/eof/types_section.rs | 11 +- 118 files changed, 12052 insertions(+), 190 deletions(-) create mode 100644 bins/revme/src/cmd/bytecode.rs delete mode 100644 bins/revme/src/cmd/eof.rs 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 diff --git a/bins/revm-test/Cargo.toml b/bins/revm-test/Cargo.toml index d3cbcc6d3c..13f3e725e0 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 = "7.2.0",default-features=false, features=["std"] } microbench = "0.5" alloy-sol-macro = "0.6.4" alloy-sol-types = "0.6.4" 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..9ffc5352c5 --- /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/eof.rs b/bins/revme/src/cmd/eof.rs deleted file mode 100644 index 75441ff058..0000000000 --- a/bins/revme/src/cmd/eof.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::path::PathBuf; -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: Vec, -} - -impl Cmd { - /// Run statetest command. - pub fn run(&self) -> Result<(), TestError> { - - } -} diff --git a/crates/interpreter/src/instructions/i256.rs b/crates/interpreter/src/instructions/i256.rs index a26ae69ad4..0cea18e56c 100644 --- a/crates/interpreter/src/instructions/i256.rs +++ b/crates/interpreter/src/instructions/i256.rs @@ -123,7 +123,7 @@ pub fn i256_mod(mut first: U256, mut second: U256) -> U256 { #[cfg(test)] mod tests { use super::*; - use core::num::Wrapping; + use core::{num::Wrapping, ops::Sub}; #[test] fn div_i256() { @@ -190,6 +190,11 @@ mod tests { 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)); + + let neg_one = U256::MAX; + let neg_two = U256::MAX.sub(&U256::from(1)); + assert_eq!(i256_div(two, neg_one), neg_two); + assert_eq!(i256_div(neg_two, neg_one), two); } #[test] diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 89efcaddd7..af9b0826a9 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -1,4 +1,4 @@ -use revm_primitives::HashSet; +use revm_primitives::{eof::EofDecodeError, HashSet}; use crate::{ instructions::utility::{read_i16, read_u16}, @@ -67,7 +67,7 @@ fn analyze(code: &[u8]) -> JumpTable { } pub fn validate_raw_eof(bytecode: Bytes) -> Result { - let eof = Eof::decode(bytecode).map_err(|_| EofError::EofDecode)?; + let eof = Eof::decode(bytecode)?; validate_eof(&eof)?; Ok(eof) } @@ -84,15 +84,10 @@ pub fn validate_eof(eof: &Eof) -> Result<(), EofError> { while let Some(eof) = queue.pop() { // iterate over types - for types in &eof.body.types_section { - types - .validate() - .map_err(|_| EofError::InvalidTypesSection)?; - } 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).map_err(|_| EofError::EofDecode)?); + queue.push(Eof::decode(container)?); } } @@ -101,10 +96,27 @@ pub fn validate_eof(eof: &Eof) -> Result<(), EofError> { } /// Validate EOF -pub fn validate_eof_codes(eof: &Eof) -> Result<(), EofError> { +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() { + // TODO(EOF) add custom error. + 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() { @@ -126,21 +138,34 @@ pub fn validate_eof_codes(eof: &Eof) -> Result<(), EofError> { } // iterate over accessed codes and check if all are accessed. if queued_codes.into_iter().any(|x| !x) { - return Err(EofError::CodeSectionNotAccessed); + return Err(EofValidationError::CodeSectionNotAccessed); } Ok(()) } -/* +/// EOF Error. +#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] +pub enum EofError { + Decode(EofDecodeError), + Validation(EofValidationError), +} -0x6000e2010005000c6001e0000d60026003e0000660036004600500 +impl From for EofError { + fn from(err: EofDecodeError) -> Self { + EofError::Decode(err) + } +} -*/ +impl From for EofError { + fn from(err: EofValidationError) -> Self { + EofError::Validation(err) + } +} -#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] -pub enum EofError { - TEST, +#[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. @@ -175,6 +200,8 @@ pub enum EofError { 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. @@ -189,10 +216,13 @@ pub enum EofError { CodeSectionNotAccessed, /// Types section invalid InvalidTypesSection, - /// EofDecode error, - EofDecode, + /// 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: @@ -216,7 +246,7 @@ pub fn validate_eof_code( data_size: usize, this_types_index: usize, types: &[TypesSection], -) -> Result, EofError> { +) -> Result, EofValidationError> { let mut accessed_codes = HashSet::::new(); let this_types = &types[this_types_index]; @@ -235,10 +265,10 @@ pub fn validate_eof_code( impl InstructionInfo { #[inline] - fn mark_as_immediate(&mut self) -> Result<(), EofError> { + fn mark_as_immediate(&mut self) -> Result<(), EofValidationError> { if self.is_jumpdest { // Jump to immediate bytes. - return Err(EofError::JumpToImmediateBytes); + return Err(EofValidationError::JumpToImmediateBytes); } self.is_immediate = true; Ok(()) @@ -271,16 +301,18 @@ pub fn validate_eof_code( let Some(opcode) = opcode else { // err unknown opcode. - return Err(EofError::UnknownOpcode); + return Err(EofValidationError::UnknownOpcode); }; if !opcode.is_eof { // Opcode is disabled in EOF - return Err(EofError::OpcodeDisabled); + return Err(EofValidationError::OpcodeDisabled); } let this_instruction = &mut jumps[i]; + //println!("next b: {next_biggest}, next s: {next_smallest} terminal: {is_after_termination} opcode: {}",opcode.name); + // 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); @@ -292,7 +324,7 @@ pub fn validate_eof_code( // 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(EofError::InstructionNotForwardAccessed); + return Err(EofValidationError::InstructionNotForwardAccessed); } is_after_termination = opcode.is_terminating_opcode; @@ -301,7 +333,7 @@ pub fn validate_eof_code( // 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(EofError::MissingImmediateBytes); + return Err(EofValidationError::MissingImmediateBytes); } // mark immediate bytes as non-jumpable. @@ -324,7 +356,7 @@ pub fn validate_eof_code( // TODO(EOF) temporarily disabled for tests // if offset == 0 { // // jump immediate instruction is not allowed. - // return Err(EofError::JumpToImmediateBytes); + // return Err(EofValidationError::JumpToImmediateBytes); // } absolute_jumpdest = vec![offset + 3 + i as isize]; // RJUMP is considered a terminating opcode. @@ -339,13 +371,13 @@ pub fn validate_eof_code( // Max index can't be zero as it becomes RJUMPI. // TODO(EOF) temporarily disabled this // if max_index == 0 { - // return Err(EofError::RJUMPVZeroMaxIndex); + // return Err(EofValidationError::RJUMPVZeroMaxIndex); // } // +1 is for max_index byte if i + 1 + rjumpv_additional_immediates >= code.len() { // Malfunctional code RJUMPV vtable is not complete - return Err(EofError::MissingRJUMPVImmediateBytes); + return Err(EofValidationError::MissingRJUMPVImmediateBytes); } // Mark vtable as immediate, max_index was already marked. @@ -361,7 +393,7 @@ pub fn validate_eof_code( // TODO(EOF) temporarily disabled for tests // if offset == 0 { // // jump immediate instruction is not allowed. - // return Err(EofError::JumpZeroOffset); + // return Err(EofValidationError::JumpZeroOffset); // } jumps.push(offset + i as isize + 2 + rjumpv_additional_immediates as isize); } @@ -371,12 +403,12 @@ pub fn validate_eof_code( 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(EofError::CodeSectionOutOfBounds); + return Err(EofValidationError::CodeSectionOutOfBounds); }; if target_types.outputs == EOF_NON_RETURNING_FUNCTION { // callf to non returning function is not allowed - return Err(EofError::CALLFNonReturningFunction); + return Err(EofValidationError::CALLFNonReturningFunction); } // stack input for this opcode is the input of the called code. stack_requirement = target_types.inputs as i32; @@ -391,7 +423,7 @@ pub fn validate_eof_code( > STACK_LIMIT as i32 { // if stack max items + called code max stack size - return Err(EofError::StackOverflow); + return Err(EofValidationError::StackOverflow); } } opcode::JUMPF => { @@ -399,7 +431,7 @@ pub fn validate_eof_code( // 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(EofError::CodeSectionOutOfBounds); + return Err(EofValidationError::CodeSectionOutOfBounds); }; // we decrement types.inputs as they are considered send to the called code. @@ -409,7 +441,7 @@ pub fn validate_eof_code( > STACK_LIMIT as i32 { // stack overflow - return Err(EofError::StackOverflow); + return Err(EofValidationError::StackOverflow); } accessed_codes.insert(target_index); @@ -417,20 +449,18 @@ pub fn validate_eof_code( if target_types.outputs == EOF_NON_RETURNING_FUNCTION { // if it is not returning stack_requirement = target_types.inputs as i32; - // if it is not returning JUMPF becomes terminating opcode. - is_after_termination = true; } else { // check if target code produces enough outputs. - if target_types.outputs < this_types.outputs { - return Err(EofError::JUMPFEnoughOutputs); + if this_types.outputs < target_types.outputs { + return Err(EofValidationError::JUMPFEnoughOutputs); } - // TODO(EOF) stack requirements for this opcode. - stack_requirement = target_types.outputs as i32 + this_types.io_diff(); + stack_requirement = this_types.outputs as i32 + target_types.inputs as i32 + - target_types.outputs as i32; // if this instruction max + target_types max is more then stack limit. if this_instruction.biggest + stack_requirement > STACK_LIMIT as i32 { - return Err(EofError::StackOverflow); + return Err(EofValidationError::StackOverflow); } } } @@ -438,7 +468,7 @@ pub fn validate_eof_code( 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(EofError::DataLoadOutOfBounds); + return Err(EofValidationError::DataLoadOutOfBounds); } } opcode::RETF => { @@ -447,12 +477,11 @@ pub fn validate_eof_code( // stack_higher_than_outputs_required // TODO(EOF) Why is this here. Why are we erroring if biggest number // is more than outputs? - return Err(EofError::RETFBiggestStackNumMoreThenOutputs); + return Err(EofValidationError::RETFBiggestStackNumMoreThenOutputs); } } opcode::DUPN => { stack_requirement = code[i + 1] as i32 + 1; - stack_io_diff = 1; } opcode::SWAPN => { stack_requirement = code[i + 1] as i32 + 2; @@ -461,25 +490,29 @@ pub fn validate_eof_code( let imm = code[i + 1]; let n = (imm >> 4) + 1; let m = (imm & 0x0F) + 1; - stack_requirement = n as i32 + m as i32; + 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(EofError::StackUnderflow); + return Err(EofValidationError::StackUnderflow); } + //println!("stack_io_diff: {}", stack_io_diff); + next_smallest = this_instruction.smallest + stack_io_diff; + next_biggest = this_instruction.biggest + stack_io_diff; + //println!("absolute_jumpdest: {absolute_jumpdest:?}"); // 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(EofError::JumpUnderflow); + return Err(EofValidationError::JumpUnderflow); } if absolute_jump >= code.len() as isize { // jump to out of bounds - return Err(EofError::JumpOverflow); + return Err(EofValidationError::JumpOverflow); } // fine to cast as bounds are checked. let absolute_jump = absolute_jump as usize; @@ -487,33 +520,30 @@ pub fn validate_eof_code( let target_jump = &mut jumps[absolute_jump]; if target_jump.is_immediate { // Jump target is immediate byte. - return Err(EofError::BackwardJumpToImmediateBytes); + 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 { + if absolute_jump <= i { + //println!("JUMP: {i} -> {target_jump:?}"); // backward jumps should have same smallest and biggest stack items. - if this_instruction.biggest != target_jump.biggest { + if target_jump.biggest != next_biggest { // wrong jumpdest. - return Err(EofError::BackwardJumpBiggestNumMismatch); + return Err(EofValidationError::BackwardJumpBiggestNumMismatch); } - if this_instruction.smallest != target_jump.smallest { + if target_jump.smallest != next_smallest { // wrong jumpdest. - return Err(EofError::BackwardJumpSmallestNumMismatch); + 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, this_instruction.smallest); - target_jump.biggest = core::cmp::max(target_jump.biggest, this_instruction.biggest); + target_jump.smallest = core::cmp::min(target_jump.smallest, next_smallest); + target_jump.biggest = core::cmp::max(target_jump.biggest, next_biggest); } } - //println!("stack_io_diff: {}", stack_io_diff); - next_smallest = this_instruction.smallest + stack_io_diff; - next_biggest = this_instruction.biggest + stack_io_diff; // additional immediate are from RJUMPV vtable. i += 1 + opcode.immediate_size as usize + rjumpv_additional_immediates; @@ -522,9 +552,8 @@ pub fn validate_eof_code( // last opcode should be terminating if !is_after_termination { // wrong termination. - return Err(EofError::LastInstructionNotTerminating); + return Err(EofValidationError::LastInstructionNotTerminating); } - // TODO integrate max so we dont need to iterate again let mut max_stack_requirement = 0; for opcode in jumps { @@ -533,8 +562,30 @@ pub fn validate_eof_code( if max_stack_requirement != types[this_types_index].max_stack_size as i32 { // stack overflow - return Err(EofError::MaxStackMismatch); + return Err(EofValidationError::MaxStackMismatch); } 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:#?}"); + } +} diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index 89aafe9d33..ba9afdf72a 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -432,7 +432,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<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; @@ -508,39 +508,39 @@ opcodes! { 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<0, 1>; - 0x81 => DUP2 => stack::dup::<2, H> => stack_io<0, 1>; - 0x82 => DUP3 => stack::dup::<3, H> => stack_io<0, 1>; - 0x83 => DUP4 => stack::dup::<4, H> => stack_io<0, 1>; - 0x84 => DUP5 => stack::dup::<5, H> => stack_io<0, 1>; - 0x85 => DUP6 => stack::dup::<6, H> => stack_io<0, 1>; - 0x86 => DUP7 => stack::dup::<7, H> => stack_io<0, 1>; - 0x87 => DUP8 => stack::dup::<8, H> => stack_io<0, 1>; - 0x88 => DUP9 => stack::dup::<9, H> => stack_io<0, 1>; - 0x89 => DUP10 => stack::dup::<10, H> => stack_io<0, 1>; - 0x8A => DUP11 => stack::dup::<11, H> => stack_io<0, 1>; - 0x8B => DUP12 => stack::dup::<12, H> => stack_io<0, 1>; - 0x8C => DUP13 => stack::dup::<13, H> => stack_io<0, 1>; - 0x8D => DUP14 => stack::dup::<14, H> => stack_io<0, 1>; - 0x8E => DUP15 => stack::dup::<15, H> => stack_io<0, 1>; - 0x8F => DUP16 => stack::dup::<16, H> => stack_io<0, 1>; - - 0x90 => SWAP1 => stack::swap::<1, H> => stack_io<0, 0>; - 0x91 => SWAP2 => stack::swap::<2, H> => stack_io<0, 0>; - 0x92 => SWAP3 => stack::swap::<3, H> => stack_io<0, 0>; - 0x93 => SWAP4 => stack::swap::<4, H> => stack_io<0, 0>; - 0x94 => SWAP5 => stack::swap::<5, H> => stack_io<0, 0>; - 0x95 => SWAP6 => stack::swap::<6, H> => stack_io<0, 0>; - 0x96 => SWAP7 => stack::swap::<7, H> => stack_io<0, 0>; - 0x97 => SWAP8 => stack::swap::<8, H> => stack_io<0, 0>; - 0x98 => SWAP9 => stack::swap::<9, H> => stack_io<0, 0>; - 0x99 => SWAP10 => stack::swap::<10, H> => stack_io<0, 0>; - 0x9A => SWAP11 => stack::swap::<11, H> => stack_io<0, 0>; - 0x9B => SWAP12 => stack::swap::<12, H> => stack_io<0, 0>; - 0x9C => SWAP13 => stack::swap::<13, H> => stack_io<0, 0>; - 0x9D => SWAP14 => stack::swap::<14, H> => stack_io<0, 0>; - 0x9E => SWAP15 => stack::swap::<15, H> => stack_io<0, 0>; - 0x9F => SWAP16 => stack::swap::<16, H> => stack_io<0, 0>; + 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>; @@ -611,21 +611,21 @@ opcodes! { 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>; - 0xE6 => DUPN => stack::dupn => stack_io<0, 0>, imm_size<1>; + 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>; - 0xED => CREATE4 => contract::txcreate:: => stack_io<5, 1>; - 0xEE => RETURNCONTRACT => contract::return_contract:: => stack_io<0, 0>, terminating; // TODO(EOF) input/output + 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; // TODO(EOF) input/output // 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<0, 0>, terminating; + 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 @@ -635,8 +635,8 @@ opcodes! { 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<0, 0>, terminating; - 0xFE => INVALID => control::invalid => stack_io<0, 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; } diff --git a/crates/interpreter/src/opcode/eof_printer.rs b/crates/interpreter/src/opcode/eof_printer.rs index 274d280e57..f72f71b391 100644 --- a/crates/interpreter/src/opcode/eof_printer.rs +++ b/crates/interpreter/src/opcode/eof_printer.rs @@ -1,19 +1,18 @@ -use revm_primitives::hex; - use self::utility::read_i16; - use super::*; +use revm_primitives::hex; +#[cfg(feature = "std")] pub fn print_eof_code(code: &[u8]) { // We can check validity and jump destinations in one pass. let mut i = 0; - let mut rjumpv_additional_immediates = 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; }; @@ -34,7 +33,7 @@ pub fn print_eof_code(code: &[u8]) { } println!(""); - rjumpv_additional_immediates = 0; + let mut rjumpv_additional_immediates = 0; if op == RJUMPV { let max_index = code[i + 1] as usize; let len = max_index + 1; @@ -49,9 +48,10 @@ pub fn print_eof_code(code: &[u8]) { for vtablei in 0..len { let offset = unsafe { read_i16(code.as_ptr().add(i + 2 + 2 * vtablei)) } as isize; - if offset == 0 { - println!("Malformed code: zero offset in RJUMPV"); - } + // TODO(EOF) for now disable checks for testing. + // if offset == 0 { + // println!("Malformed code: zero offset in RJUMPV"); + // } println!("RJUMPV[{vtablei}]: 0x{offset:04X}({offset})"); } 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/eof.rs b/crates/interpreter/tests/eof.rs index f313e4667a..d74f7cb719 100644 --- a/crates/interpreter/tests/eof.rs +++ b/crates/interpreter/tests/eof.rs @@ -1,9 +1,10 @@ use revm_interpreter::analysis::{validate_raw_eof, EofError}; -use revm_primitives::{Bytes, Eof, HashMap}; +use revm_primitives::{Bytes, Eof}; use serde::Deserialize; use std::{ collections::BTreeMap, path::{Path, PathBuf}, + time::Instant, }; use walkdir::{DirEntry, WalkDir}; @@ -11,64 +12,117 @@ use walkdir::{DirEntry, WalkDir}; // EOF_InvalidJumpDestination /* -result:Result { result: false, exception: Some("EOF_InvalidJumpDestination") } -revm result:Ok(Eof { header: EofHeader { types_size: 4, code_sizes: [7], container_sizes: [], data_size: 0, sum_code_sizes: 7, sum_container_sizes: 0 }, body: EofBody { types_section: [TypesSection { inputs: 0, outputs: 128, max_stack_size: 1 }], -code_section: [0x6001e200ffff00], container_section: [], data_section: 0x, is_data_filled: true }, raw: Some(0xef0001010004020001000704000000008000016001e200ffff00) }) - - -result:Result { result: false, exception: Some("EOF_InvalidTypeSectionSize") } -revm result:Ok(Eof { header: EofHeader { types_size: 8, code_sizes: [3], container_sizes: [], data_size: 4, sum_code_sizes: 3, sum_container_sizes: 0 }, body: EofBody { types_section: [TypesSection { inputs: 0, outputs: 128, max_stack_size: 1 }, TypesSection { inputs: 0, outputs: 0, max_stack_size: 0 }], -code_section: [0x305000], container_section: [], data_section: 0x0bad60a7, is_data_filled: true }, raw: Some(0xef000101000802000100030400040000800001000000003050000bad60a7) }) -bytes:0xef000101000802000100030400040000800001000000003050000bad60a7 - - +Types of error: { + FalsePossitive: 10, + Error( + Decode( + InvalidTerminalByte, + ), + ): 3, + Error( + Validation( + OpcodeDisabled, + ), + ): 19, +} +Passed tests: 2012/2044 */ - #[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: 9, +} +Passed tests: 1254/1263 + +EOF_InvalidNumberOfOutputs x7 +EOF_EofCreateWithTruncatedContainer +EOF_InvalidContainerSectionIndex +*/ #[test] -fn eof_validation_eip3540() { - let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP3540"); +fn eof_validation() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/eof_validation"); run_test(&eof_tests) } -// One MaxStackMismatch +/* +Types of error: { + OpcodeDisabled: 8, +} +Passed tests: 194/202 +*/ #[test] -fn eof_validation_eip3670() { - let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP3670"); +fn eof_validation_eip5450() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP5450"); run_test(&eof_tests) } -// BIG CODE 5b5b5b5b.. +/* +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_eip4200() { - let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP4200"); +fn eof_validation_eip3670() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP3670"); run_test(&eof_tests) } -// EOF_InvalidFirstSectionType +/* +// One big bytecode. +Types of error: { + TEST: 1, +} +Passed tests: 34/35 +*/ #[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) + run_test(&eof_tests); + println!("Elapsed:{:?}", inst.elapsed()) } -// +/// PASSING ALL #[test] -fn eof_validation_eip5450() { - let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP5450"); +fn eof_validation_eip3540() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP3540"); run_test(&eof_tests) } +/// ALL PASSED +#[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; - let mut types_of_error: HashMap = HashMap::new(); + + #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + enum ErrorType { + FalsePossitive, + 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(); @@ -79,14 +133,18 @@ pub fn run_test(path: &Path) { if res.is_ok() != test_vector.results.prague.result { let eof = Eof::decode(test_vector.code.clone()); println!( - "Test failed: {} - {}\nresult:{:?}\nrevm result:{:?}\nbytes:{:?}\neof: {eof:?}", + "\nTest failed: {} - {}\nresult:{:?}\nrevm result:{:#?}\nbytes:{:?}\neof:{eof:#?}", name, vector_name, test_vector.results.prague, res, test_vector.code ); *types_of_error - .entry(res.err().unwrap_or(EofError::TEST)) + .entry( + res.err() + .map(|i| ErrorType::Error(i)) + .unwrap_or(ErrorType::FalsePossitive), + ) .or_default() += 1; } else { - println!("Test passed: {} - {}", name, vector_name); + //println!("Test passed: {} - {}", name, vector_name); passed_tests += 1; } } diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index 16d77505d2..2491de6034 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -50,7 +50,7 @@ impl Eof { &self.body.data_section } - pub fn decode(raw: Bytes) -> Result { + pub fn decode(raw: Bytes) -> Result { let (header, _) = EofHeader::decode(&raw)?; let body = EofBody::decode(&raw, &header)?; Ok(Self { @@ -68,6 +68,39 @@ impl Eof { } } +/// 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 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, + /// There should be at least one size. + NonSizes, + /// Missing size. + ShortInputForSizes, + /// Size cant be zero + ZeroSize, +} + #[cfg(test)] mod test { diff --git a/crates/primitives/src/bytecode/eof/body.rs b/crates/primitives/src/bytecode/eof/body.rs index e0e8180ab3..7e841e0715 100644 --- a/crates/primitives/src/bytecode/eof/body.rs +++ b/crates/primitives/src/bytecode/eof/body.rs @@ -1,4 +1,4 @@ -use super::{EofHeader, TypesSection}; +use super::{EofDecodeError, EofHeader, TypesSection}; use crate::Bytes; use std::vec::Vec; @@ -18,18 +18,18 @@ impl EofBody { self.code_section.get(index) } - pub fn decode(input: &Bytes, header: &EofHeader) -> Result { + 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(()); + return Err(EofDecodeError::MissingBodyWithoutData); } if input.len() > header_len + full_body_len { - return Err(()); + return Err(EofDecodeError::DanglingData); } let mut body = EofBody::default(); diff --git a/crates/primitives/src/bytecode/eof/decode_helpers.rs b/crates/primitives/src/bytecode/eof/decode_helpers.rs index 6ab139255a..50ebaf6bb9 100644 --- a/crates/primitives/src/bytecode/eof/decode_helpers.rs +++ b/crates/primitives/src/bytecode/eof/decode_helpers.rs @@ -1,16 +1,18 @@ +use super::EofDecodeError; + #[inline] -pub(crate) fn consume_u8(input: &[u8]) -> Result<(&[u8], u8), ()> { +pub(crate) fn consume_u8(input: &[u8]) -> Result<(&[u8], u8), EofDecodeError> { if input.is_empty() { - return Err(()); + 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), ()> { +pub(crate) fn consume_u16(input: &[u8]) -> Result<(&[u8], u16), EofDecodeError> { if input.len() < 2 { - return Err(()); + 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 index e469cc6e4b..69bc67276f 100644 --- a/crates/primitives/src/bytecode/eof/header.rs +++ b/crates/primitives/src/bytecode/eof/header.rs @@ -1,4 +1,7 @@ -use super::decode_helpers::{consume_u16, consume_u8}; +use super::{ + decode_helpers::{consume_u16, consume_u8}, + EofDecodeError, +}; use std::vec::Vec; /// EOF Header containing @@ -29,16 +32,16 @@ const KIND_CONTAINER: u8 = 3; const KIND_DATA: u8 = 4; #[inline] -fn consume_header_section_size(input: &[u8]) -> Result<(&[u8], Vec, usize), ()> { +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(()); + return Err(EofDecodeError::NonSizes); } let byte_size = (num_sections * 2) as usize; if input.len() < byte_size { - return Err(()); + return Err(EofDecodeError::ShortInputForSizes); } let mut sizes = Vec::with_capacity(num_sections as usize); let mut sum = 0; @@ -47,7 +50,7 @@ fn consume_header_section_size(input: &[u8]) -> Result<(&[u8], Vec, usize), // 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(()); + return Err(EofDecodeError::ZeroSize); } sum += code_size as usize; sizes.push(code_size); @@ -92,25 +95,25 @@ impl EofHeader { self.size() + self.body_size() } - pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), ()> { + 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(()); + return Err(EofDecodeError::InvalidEOFMagicNumber); } // version 1 byte 0x01 EOF version let (input, version) = consume_u8(input)?; if version != 0x01 { - return Err(()); + 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(()); + return Err(EofDecodeError::InvalidTypesKind); } // types_size 2 bytes 0x0004-0xFFFF @@ -121,7 +124,7 @@ impl EofHeader { // 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(()); + return Err(EofDecodeError::InvalidCodeKind); } // code_sections_sizes @@ -137,10 +140,14 @@ impl EofHeader { let (input, sizes, sum) = consume_header_section_size(input)?; 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(()), + _ => return Err(EofDecodeError::InvalidKindAfterCode), }; // data_size 2 bytes 0x0000-0xFFFF 16-bit @@ -151,9 +158,9 @@ impl EofHeader { header.data_size = data_size; // terminator 1 byte 0x00 marks the end of the EofHeader - let (_, terminator) = consume_u8(input)?; + let (input, terminator) = consume_u8(input)?; if terminator != KIND_TERMINAL { - return Err(()); + return Err(EofDecodeError::InvalidTerminalByte); } Ok((header, input)) @@ -208,6 +215,15 @@ mod tests { #[test] fn decode_header_not_terminated() { let mut input = hex!("ef0001010004"); - assert_eq!(EofHeader::decode(&mut input), Err(())); + assert_eq!( + EofHeader::decode(&mut input), + Err(EofDecodeError::InvalidTerminalByte) + ); + } + + #[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 index 8225f7f204..daaa7478e1 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -1,4 +1,7 @@ -use super::decode_helpers::{consume_u16, consume_u8}; +use super::{ + decode_helpers::{consume_u16, consume_u8}, + EofDecodeError, +}; /// TODO(EOF) Chekc if max_stack_size >= inputs. #[derive(Debug, Clone, Default, Hash, PartialEq, Eq, Copy)] @@ -23,7 +26,7 @@ impl TypesSection { } #[inline] - pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), ()> { + 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)?; @@ -36,9 +39,9 @@ impl TypesSection { Ok((section, input)) } - pub fn validate(&self) -> Result<(), ()> { + pub fn validate(&self) -> Result<(), EofDecodeError> { if self.inputs > 0x7f || self.outputs > 0x80 || self.max_stack_size > 0x03FF { - return Err(()); + return Err(EofDecodeError::InvalidTypesSection); } Ok(()) } From c1c31ecb6412e297e513eac1bd3e24d3c1c86646 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 2 Apr 2024 14:38:49 +0200 Subject: [PATCH 36/54] pass most of validation tests --- .../interpreter/src/interpreter/analysis.rs | 34 +++++++++++-- crates/interpreter/src/opcode.rs | 4 +- crates/interpreter/tests/eof.rs | 36 +++++--------- crates/primitives/src/bytecode/eof.rs | 37 ++++++++++++-- crates/primitives/src/bytecode/eof/body.rs | 16 +++++++ crates/primitives/src/bytecode/eof/header.rs | 48 +++++++++++++++++++ .../src/bytecode/eof/types_section.rs | 6 +++ crates/revm/src/context/inner_evm_context.rs | 1 - 8 files changed, 147 insertions(+), 35 deletions(-) diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index af9b0826a9..62fc244829 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -99,7 +99,6 @@ pub fn validate_eof(eof: &Eof) -> Result<(), EofError> { 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() { - // TODO(EOF) add custom error. return Err(EofValidationError::InvalidTypesSection); } @@ -125,6 +124,7 @@ pub fn validate_eof_codes(eof: &Eof) -> Result<(), EofValidationError> { code, eof.header.data_size as usize, index, + eof.body.container_section.len(), &eof.body.types_section, )?; @@ -186,6 +186,8 @@ pub enum EofValidationError { 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. @@ -194,6 +196,8 @@ pub enum EofValidationError { StackOverflow, /// JUMPF needs to have enough outputs. JUMPFEnoughOutputs, + /// JUMPF Stack + JUMPFStackHigherThanOutputs, /// DATA load out of bounds. DataLoadOutOfBounds, /// TODO(EOF) check this error. @@ -245,6 +249,7 @@ 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(); @@ -443,7 +448,6 @@ pub fn validate_eof_code( // stack overflow return Err(EofValidationError::StackOverflow); } - accessed_codes.insert(target_index); if target_types.outputs == EOF_NON_RETURNING_FUNCTION { @@ -458,12 +462,24 @@ pub fn validate_eof_code( 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 { @@ -474,9 +490,6 @@ pub fn validate_eof_code( opcode::RETF => { stack_requirement = this_types.outputs as i32; if this_instruction.biggest > stack_requirement { - // stack_higher_than_outputs_required - // TODO(EOF) Why is this here. Why are we erroring if biggest number - // is more than outputs? return Err(EofValidationError::RETFBiggestStackNumMoreThenOutputs); } } @@ -588,4 +601,15 @@ mod test { validate_raw_eof(hex!("ef000101000c02000300040004000204000000008000020002000100010001e30001005fe500025fe4").into()); assert!(err.is_ok(), "{err:#?}"); } + + #[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::JUMPFEnoughOutputs)) + ); + } } diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index ba9afdf72a..105c48ad4f 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -618,9 +618,9 @@ opcodes! { // 0xE9 // 0xEA // 0xEB - 0xEC => EOFCREATE => contract::eofcreate:: => stack_io<4, 1>, imm_size<1>; + 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; // TODO(EOF) input/output + 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; diff --git a/crates/interpreter/tests/eof.rs b/crates/interpreter/tests/eof.rs index d74f7cb719..0b9841b5ed 100644 --- a/crates/interpreter/tests/eof.rs +++ b/crates/interpreter/tests/eof.rs @@ -13,19 +13,13 @@ use walkdir::{DirEntry, WalkDir}; /* Types of error: { - FalsePossitive: 10, - Error( - Decode( - InvalidTerminalByte, - ), - ): 3, + FalsePossitive: 1, Error( Validation( OpcodeDisabled, ), ): 19, } -Passed tests: 2012/2044 */ #[test] fn eof_run_all_tests() { @@ -35,13 +29,10 @@ fn eof_run_all_tests() { /* Types of error: { - FalsePossitive: 9, + FalsePossitive: 1, } -Passed tests: 1254/1263 - -EOF_InvalidNumberOfOutputs x7 -EOF_EofCreateWithTruncatedContainer -EOF_InvalidContainerSectionIndex +Passed tests: 1262/1263 +EOF_EofCreateWithTruncatedContainer TODO */ #[test] fn eof_validation() { @@ -54,6 +45,7 @@ Types of error: { OpcodeDisabled: 8, } Passed tests: 194/202 +Probably same a below. */ #[test] fn eof_validation_eip5450() { @@ -73,7 +65,7 @@ Passed tests: 290/299 // 0x38e4 CODESIZE validInvalid - validInvalid_4 // 0x60013f00 EXTCODEHASH validInvalid - validInvalid_39 // 0x60018080803c00 EXTCODECOPY validInvalid - validInvalid_37 -// 0x60013b00 eXTCODESIZE validInvalid - validInvalid_36 +// 0x60013b00 EXTCODESIZE validInvalid - validInvalid_36 // 0x600180803900 CODECOPY validInvalid - validInvalid_35 // 0x5a00 GAS validInvalid - validInvalid_60 // 0xfe opcode is considered valid, should it be disabled? @@ -83,13 +75,7 @@ fn eof_validation_eip3670() { run_test(&eof_tests) } -/* -// One big bytecode. -Types of error: { - TEST: 1, -} -Passed tests: 34/35 -*/ +/// PASSING ALL #[test] fn eof_validation_eip4750() { let inst = Instant::now(); @@ -133,8 +119,12 @@ pub fn run_test(path: &Path) { if res.is_ok() != test_vector.results.prague.result { let eof = Eof::decode(test_vector.code.clone()); println!( - "\nTest failed: {} - {}\nresult:{:?}\nrevm result:{:#?}\nbytes:{:?}\neof:{eof:#?}", - name, vector_name, test_vector.results.prague, res, test_vector.code + "\nTest failed: {} - {}\nresult:{:?}\nrevm result:{:#?}\nbytes:{:?}\n", + name, + vector_name, + test_vector.results.prague, + false, /*res*/ + test_vector.code ); *types_of_error .entry( diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index 2491de6034..edf6fb25a5 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -50,6 +50,28 @@ impl Eof { &self.body.data_section } + /// Re-encode the raw EOF bytes. + pub fn reencode_inner(&mut self) { + self.raw = Some(self.encode_slow().into()) + } + + /// 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() + } + + /// Encode the EOF into bytes. + pub fn encode(&self) -> Bytes { + if let Some(raw) = &self.raw { + raw.clone() + } else { + self.encode_slow() + } + } + pub fn decode(raw: Bytes) -> Result { let (header, _) = EofHeader::decode(&raw)?; let body = EofBody::decode(&raw, &header)?; @@ -79,6 +101,8 @@ pub enum EofDecodeError { DanglingData, /// Invalid types section data. InvalidTypesSection, + /// Invalid types section size. + InvalidTypesSectionSize, /// Invalid EOF magic number. InvalidEOFMagicNumber, /// Invalid EOF version. @@ -93,12 +117,16 @@ pub enum EofDecodeError { 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 numbers. + TooManyCodeSections } #[cfg(test)] @@ -109,14 +137,15 @@ mod test { #[test] fn decode_eof() { - let bytes = alloy_primitives::bytes!("ef000101000402000100010400000000800000fe"); - Eof::decode(bytes).unwrap(); + let bytes = bytes!("ef000101000402000100010400000000800000fe"); + let eof = Eof::decode(bytes.clone()).unwrap(); + assert_eq!(bytes, eof.encode_slow()); } #[test] fn data_slice() { - let bytes = alloy_primitives::bytes!("ef000101000402000100010400000000800000fe"); - let mut eof = Eof::decode(bytes).unwrap(); + 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]); diff --git a/crates/primitives/src/bytecode/eof/body.rs b/crates/primitives/src/bytecode/eof/body.rs index 7e841e0715..6986244bde 100644 --- a/crates/primitives/src/bytecode/eof/body.rs +++ b/crates/primitives/src/bytecode/eof/body.rs @@ -18,6 +18,22 @@ impl EofBody { self.code_section.get(index) } + 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); + } + pub fn decode(input: &Bytes, header: &EofHeader) -> Result { let header_len = header.size(); let partial_body_len = diff --git a/crates/primitives/src/bytecode/eof/header.rs b/crates/primitives/src/bytecode/eof/header.rs index 69bc67276f..d747b0976d 100644 --- a/crates/primitives/src/bytecode/eof/header.rs +++ b/crates/primitives/src/bytecode/eof/header.rs @@ -95,6 +95,41 @@ impl EofHeader { self.size() + self.body_size() } + 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); + } + pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), EofDecodeError> { let mut header = EofHeader::default(); @@ -121,6 +156,10 @@ impl EofHeader { 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 { @@ -129,6 +168,15 @@ impl EofHeader { // code_sections_sizes let (input, sizes, sum) = consume_header_section_size(input)?; + + if sizes.len() > 1024 { + return Err(EofDecodeError::TooManyCodeSections); + } + + if sizes.len() != (types_size / 4) as usize { + return Err(EofDecodeError::MismatchCodeAndTypesSize); + } + header.code_sizes = sizes; header.sum_code_sizes = sum; diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs index daaa7478e1..dc7cc198e5 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -25,6 +25,12 @@ impl TypesSection { self.outputs as i32 - self.inputs as i32 } + 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()); + } + #[inline] pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), EofDecodeError> { let (input, inputs) = consume_u8(input)?; diff --git a/crates/revm/src/context/inner_evm_context.rs b/crates/revm/src/context/inner_evm_context.rs index 87fbfdeaa2..f6ec6a299f 100644 --- a/crates/revm/src/context/inner_evm_context.rs +++ b/crates/revm/src/context/inner_evm_context.rs @@ -219,7 +219,6 @@ impl InnerEvmContext { } /// Make create frame. - /// TODO(EOF) refactor with crate function. #[inline] pub fn make_eofcreate_frame( &mut self, From b8f7fadc320a185fbfad11d36d933152f2675f37 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 2 Apr 2024 21:00:17 +0200 Subject: [PATCH 37/54] bounds check moved to decode --- crates/interpreter/tests/eof.rs | 14 ++++---- crates/primitives/src/bytecode/eof.rs | 8 +++-- crates/primitives/src/bytecode/eof/header.rs | 38 +++++--------------- 3 files changed, 20 insertions(+), 40 deletions(-) diff --git a/crates/interpreter/tests/eof.rs b/crates/interpreter/tests/eof.rs index 0b9841b5ed..4cdaf6fa3d 100644 --- a/crates/interpreter/tests/eof.rs +++ b/crates/interpreter/tests/eof.rs @@ -8,8 +8,6 @@ use std::{ }; use walkdir::{DirEntry, WalkDir}; -// EOF_InvalidTypeSectionSize -// EOF_InvalidJumpDestination /* Types of error: { @@ -45,7 +43,7 @@ Types of error: { OpcodeDisabled: 8, } Passed tests: 194/202 -Probably same a below. +Probably same as below. */ #[test] fn eof_validation_eip5450() { @@ -91,7 +89,7 @@ fn eof_validation_eip3540() { run_test(&eof_tests) } -/// ALL PASSED +/// PASSING ALL #[test] fn eof_validation_eip4200() { let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP4200"); @@ -105,7 +103,7 @@ pub fn run_test(path: &Path) { #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] enum ErrorType { - FalsePossitive, + FalsePositive, Error(EofError), } let mut types_of_error: BTreeMap = BTreeMap::new(); @@ -119,18 +117,18 @@ pub fn run_test(path: &Path) { if res.is_ok() != test_vector.results.prague.result { let eof = Eof::decode(test_vector.code.clone()); println!( - "\nTest failed: {} - {}\nresult:{:?}\nrevm result:{:#?}\nbytes:{:?}\n", + "\nTest failed: {} - {}\nresult:{:?}\nrevm err_result:{:#?}\nbytes:{:?}\n,eof:{eof:#?}", name, vector_name, test_vector.results.prague, - false, /*res*/ + res.as_ref().err(), test_vector.code ); *types_of_error .entry( res.err() .map(|i| ErrorType::Error(i)) - .unwrap_or(ErrorType::FalsePossitive), + .unwrap_or(ErrorType::FalsePositive), ) .or_default() += 1; } else { diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index edf6fb25a5..6f61003b0f 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -125,8 +125,12 @@ pub enum EofDecodeError { ShortInputForSizes, /// Size cant be zero ZeroSize, - /// Invalid code numbers. - TooManyCodeSections + /// Invalid code number. + TooManyCodeSections, + /// Invalid number of code sections. + ZeroCodeSections, + /// Invalid container number. + TooManyContainerSections, } #[cfg(test)] diff --git a/crates/primitives/src/bytecode/eof/header.rs b/crates/primitives/src/bytecode/eof/header.rs index d747b0976d..78b76755b1 100644 --- a/crates/primitives/src/bytecode/eof/header.rs +++ b/crates/primitives/src/bytecode/eof/header.rs @@ -173,6 +173,10 @@ impl EofHeader { return Err(EofDecodeError::TooManyCodeSections); } + if sizes.is_empty() { + return Err(EofDecodeError::ZeroCodeSections); + } + if sizes.len() != (types_size / 4) as usize { return Err(EofDecodeError::MismatchCodeAndTypesSize); } @@ -186,6 +190,10 @@ impl EofHeader { 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)?; @@ -213,36 +221,6 @@ impl EofHeader { Ok((header, input)) } - - pub fn validate(&self) -> Result<(), ()> { - // minimum valid header size is 15 bytes (Checked in decode) - // version must be 0x01 (Checked in decode) - - // types_size is divisible by 4 - if self.types_size % 4 != 0 { - return Err(()); - } - - // the number of code sections must be equal to types_size / 4 - if self.code_sizes.len() != self.types_size as usize / 4 { - return Err(()); - } - // the number of code sections must not exceed 1024 - if self.code_sizes.len() > 1024 { - return Err(()); - } - // code_size may not be 0 - if self.code_sizes.is_empty() { - return Err(()); - } - // the number of container sections must not exceed 256 - if self.container_sizes.len() > 256 { - return Err(()); - } - // container_size may not be 0, but container sections are optional - // (Checked in decode) - Ok(()) - } } #[cfg(test)] From 1ae956391ac57c8dfa4c7cd80cfcd6aa15fe3c91 Mon Sep 17 00:00:00 2001 From: rakita Date: Wed, 3 Apr 2024 10:53:16 +0200 Subject: [PATCH 38/54] Fix merge compilation, fmt --- .../interpreter/src/instructions/contract.rs | 24 +++++++++---------- .../src/instructions/contract/call_helpers.rs | 2 +- .../interpreter/src/instructions/control.rs | 14 +++++------ crates/interpreter/src/instructions/data.rs | 8 +++---- crates/interpreter/src/instructions/host.rs | 12 +++++----- .../interpreter/src/instructions/host_env.rs | 2 +- crates/interpreter/src/instructions/stack.rs | 6 ++--- crates/interpreter/src/instructions/system.rs | 8 +++---- crates/interpreter/src/opcode.rs | 11 +++++---- crates/interpreter/tests/eof.rs | 1 - crates/revm/src/inspector/eip3155.rs | 3 +-- 11 files changed, 45 insertions(+), 46 deletions(-) diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index a9817342c0..5ec88ea9e7 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -32,7 +32,7 @@ pub fn resize_memory( } } -pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) { +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 }; @@ -89,7 +89,7 @@ pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; } -pub fn txcreate(interpreter: &mut Interpreter, _host: &mut H) { +pub fn txcreate(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, EOF_CREATE_GAS); pop!( @@ -156,7 +156,7 @@ pub fn txcreate(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn return_contract(interpreter: &mut Interpreter, _host: &mut H) { +pub fn return_contract(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); } @@ -173,7 +173,7 @@ pub fn extcall_input(interpreter: &mut Interpreter) -> Option { )) } -pub fn extcall_gas_calc( +pub fn extcall_gas_calc( interpreter: &mut Interpreter, host: &mut H, target: Address, @@ -211,7 +211,7 @@ pub fn extcall_gas_calc( Some(gas_limit) } -pub fn extcall(interpreter: &mut Interpreter, host: &mut H) { +pub fn extcall(interpreter: &mut Interpreter, host: &mut H) { error_on_disabled_eof!(interpreter); pop_address!(interpreter, target_address); @@ -246,7 +246,7 @@ pub fn extcall(interpreter: &mut Interpreter, host: &mut H) interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn extdcall(interpreter: &mut Interpreter, host: &mut H) { +pub fn extdcall(interpreter: &mut Interpreter, host: &mut H) { error_on_disabled_eof!(interpreter); pop_address!(interpreter, target_address); @@ -279,7 +279,7 @@ pub fn extdcall(interpreter: &mut Interpreter, host: &mut H interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn extscall(interpreter: &mut Interpreter, host: &mut H) { +pub fn extscall(interpreter: &mut Interpreter, host: &mut H) { error_on_disabled_eof!(interpreter); pop_address!(interpreter, target_address); @@ -310,7 +310,7 @@ pub fn extscall(interpreter: &mut Interpreter, host: &mut H) { interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn create( +pub fn create( interpreter: &mut Interpreter, host: &mut H, ) { @@ -380,7 +380,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) { panic_on_eof!(interpreter); pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); @@ -437,7 +437,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) { panic_on_eof!(interpreter); pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); @@ -489,7 +489,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) { panic_on_eof!(interpreter); check!(interpreter, HOMESTEAD); pop!(interpreter, local_gas_limit); @@ -531,7 +531,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) { panic_on_eof!(interpreter); check!(interpreter, BYZANTIUM); pop!(interpreter, local_gas_limit); diff --git a/crates/interpreter/src/instructions/contract/call_helpers.rs b/crates/interpreter/src/instructions/contract/call_helpers.rs index 4d0e49617f..2640c3b953 100644 --- a/crates/interpreter/src/instructions/contract/call_helpers.rs +++ b/crates/interpreter/src/instructions/contract/call_helpers.rs @@ -45,7 +45,7 @@ pub fn resize_memory_and_return_range( } #[inline] -pub fn calc_call_gas( +pub fn calc_call_gas( interpreter: &mut Interpreter, is_cold: bool, has_transfer: bool, diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index d2687cfbcd..8852dff8ed 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -14,7 +14,7 @@ pub fn rjump(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset + 2) }; } -pub fn rjumpi(interpreter: &mut Interpreter, _host: &mut H) { +pub fn rjumpi(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::CONDITION_JUMP_GAS); pop!(interpreter, condition); @@ -28,7 +28,7 @@ pub fn rjumpi(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset) }; } -pub fn rjumpv(interpreter: &mut Interpreter, _host: &mut H) { +pub fn rjumpv(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::CONDITION_JUMP_GAS); pop!(interpreter, case); @@ -53,7 +53,7 @@ pub fn rjumpv(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset) }; } -pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { +pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { panic_on_eof!(interpreter); gas!(interpreter, gas::MID); pop!(interpreter, dest); @@ -85,7 +85,7 @@ pub fn jumpdest_or_nop(interpreter: &mut Interpreter, _host: & gas!(interpreter, gas::JUMPDEST); } -pub fn callf(interpreter: &mut Interpreter, _host: &mut H) { +pub fn callf(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::LOW); @@ -106,7 +106,7 @@ pub fn callf(interpreter: &mut Interpreter, _host: &mut H) { interpreter.load_eof_code(idx, 0) } -pub fn retf(interpreter: &mut Interpreter, _host: &mut H) { +pub fn retf(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::RETF_GAS); @@ -117,7 +117,7 @@ pub fn retf(interpreter: &mut Interpreter, _host: &mut H) { interpreter.load_eof_code(fframe.idx, fframe.pc); } -pub fn jumpf(interpreter: &mut Interpreter, _host: &mut H) { +pub fn jumpf(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::LOW); @@ -129,7 +129,7 @@ pub fn jumpf(interpreter: &mut Interpreter, _host: &mut H) { interpreter.load_eof_code(idx, 0) } -pub fn pc(interpreter: &mut Interpreter, _host: &mut H) { +pub fn pc(interpreter: &mut Interpreter, _host: &mut H) { panic_on_eof!(interpreter); gas!(interpreter, gas::BASE); // - 1 because we have already advanced the instruction pointer in `Interpreter::step` diff --git a/crates/interpreter/src/instructions/data.rs b/crates/interpreter/src/instructions/data.rs index 80cea3b39e..1475d24c41 100644 --- a/crates/interpreter/src/instructions/data.rs +++ b/crates/interpreter/src/instructions/data.rs @@ -6,7 +6,7 @@ use crate::{ Host, }; -pub fn data_load(interpreter: &mut Interpreter, _host: &mut H) { +pub fn data_load(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, DATA_LOAD_GAS); pop_top!(interpreter, offset); @@ -26,7 +26,7 @@ pub fn data_load(interpreter: &mut Interpreter, _host: &mut H) { *offset = U256::from_be_bytes(word); } -pub fn data_loadn(interpreter: &mut Interpreter, _host: &mut H) { +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; @@ -47,7 +47,7 @@ pub fn data_loadn(interpreter: &mut Interpreter, _host: &mut H) interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(2) }; } -pub fn data_size(interpreter: &mut Interpreter, _host: &mut H) { +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; @@ -55,7 +55,7 @@ pub fn data_size(interpreter: &mut Interpreter, _host: &mut H) { push!(interpreter, U256::from(data_size)); } -pub fn data_copy(interpreter: &mut Interpreter, _host: &mut H) { +pub fn data_copy(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_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 9af3e99365..f400bb4f95 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -39,7 +39,7 @@ pub fn selfbalance(interpreter: &mut Interpreter, push!(interpreter, balance); } -pub fn extcodesize(interpreter: &mut Interpreter, host: &mut H) { +pub fn extcodesize(interpreter: &mut Interpreter, host: &mut H) { panic_on_eof!(interpreter); pop_address!(interpreter, address); let Some((code, is_cold)) = host.code(address) else { @@ -58,7 +58,7 @@ pub fn extcodesize(interpreter: &mut Interpreter, ho } /// EIP-1052: EXTCODEHASH opcode -pub fn extcodehash(interpreter: &mut Interpreter, host: &mut H) { +pub fn extcodehash(interpreter: &mut Interpreter, host: &mut H) { panic_on_eof!(interpreter); check!(interpreter, CONSTANTINOPLE); pop_address!(interpreter, address); @@ -76,7 +76,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) { panic_on_eof!(interpreter); pop_address!(interpreter, address); pop!(interpreter, memory_offset, code_offset, len_u256); @@ -134,7 +134,7 @@ pub fn sload(interpreter: &mut Interpreter, host: push!(interpreter, value); } -pub fn sstore(interpreter: &mut Interpreter, host: &mut H) { +pub fn sstore(interpreter: &mut Interpreter, host: &mut H) { error_on_static_call!(interpreter); pop!(interpreter, index, value); @@ -178,7 +178,7 @@ pub fn tload(interpreter: &mut Interpreter, host: *index = host.tload(interpreter.contract.target_address, *index); } -pub fn log(interpreter: &mut Interpreter, host: &mut H) { +pub fn log(interpreter: &mut Interpreter, host: &mut H) { error_on_static_call!(interpreter); pop!(interpreter, offset, len); @@ -211,7 +211,7 @@ pub fn log(interpreter: &mut Interpreter, host: host.log(log); } -pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut H) { +pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut H) { panic_on_eof!(interpreter); error_on_static_call!(interpreter); pop_address!(interpreter, target); diff --git a/crates/interpreter/src/instructions/host_env.rs b/crates/interpreter/src/instructions/host_env.rs index 7578b6fa5c..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 block_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/stack.rs b/crates/interpreter/src/instructions/stack.rs index 813998d59f..fa6c1be91c 100644 --- a/crates/interpreter/src/instructions/stack.rs +++ b/crates/interpreter/src/instructions/stack.rs @@ -51,7 +51,7 @@ pub fn swap(interpreter: &mut Interpreter, _ho } } -pub fn dupn(interpreter: &mut Interpreter, _host: &mut H) { +pub fn dupn(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::VERYLOW); let imm = unsafe { *interpreter.instruction_pointer }; @@ -61,7 +61,7 @@ pub fn dupn(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; } -pub fn swapn(interpreter: &mut Interpreter, _host: &mut H) { +pub fn swapn(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::VERYLOW); let imm = unsafe { *interpreter.instruction_pointer }; @@ -71,7 +71,7 @@ pub fn swapn(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; } -pub fn exchange(interpreter: &mut Interpreter, _host: &mut H) { +pub fn exchange(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::VERYLOW); let imm = unsafe { *interpreter.instruction_pointer }; diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index 451f47f896..984f7bd857 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -29,13 +29,13 @@ pub fn caller(interpreter: &mut Interpreter, _host: &mut H) { 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) { panic_on_eof!(interpreter); 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) { panic_on_eof!(interpreter); pop!(interpreter, memory_offset, code_offset, len); let len = as_usize_or_fail!(interpreter, len); @@ -136,7 +136,7 @@ pub fn returndatacopy(interpreter: &mut Interprete } /// Part of EOF https://eips.ethereum.org/EIPS/eip-7069 -pub fn returndataload(interpreter: &mut Interpreter, _host: &mut H) { +pub fn returndataload(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, offset); @@ -150,7 +150,7 @@ pub fn returndataload(interpreter: &mut Interpreter, _host: &mut B256::from_slice(&interpreter.return_data_buffer[offset_usize..offset_usize + 32]).into(); } -pub fn gas(interpreter: &mut Interpreter, _host: &mut H) { +pub fn gas(interpreter: &mut Interpreter, _host: &mut H) { panic_on_eof!(interpreter); gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.gas.remaining())); diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index 105c48ad4f..a3301b3a78 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -90,13 +90,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; @@ -339,7 +340,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/tests/eof.rs b/crates/interpreter/tests/eof.rs index 4cdaf6fa3d..bd4b2cb933 100644 --- a/crates/interpreter/tests/eof.rs +++ b/crates/interpreter/tests/eof.rs @@ -8,7 +8,6 @@ use std::{ }; use walkdir::{DirEntry, WalkDir}; - /* Types of error: { FalsePossitive: 1, diff --git a/crates/revm/src/inspector/eip3155.rs b/crates/revm/src/inspector/eip3155.rs index a073e5d183..22438fdb7b 100644 --- a/crates/revm/src/inspector/eip3155.rs +++ b/crates/revm/src/inspector/eip3155.rs @@ -1,8 +1,7 @@ use crate::{ inspectors::GasInspector, interpreter::{ - CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter, - InterpreterResult, + CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter, InterpreterResult, }, primitives::{db::Database, hex, HashMap, B256, U256}, EvmContext, Inspector, From 7b73779a67a6a1279386be908a62991947d8a434 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 04:09:28 +0200 Subject: [PATCH 39/54] TXCREATE work --- crates/interpreter/src/call_inputs.rs | 11 +- crates/interpreter/src/eof_create_inputs.rs | 2 +- crates/interpreter/src/host.rs | 3 +- crates/interpreter/src/instruction_result.rs | 18 ++-- .../interpreter/src/instructions/contract.rs | 102 ++++++++++++++---- crates/interpreter/src/instructions/macros.rs | 11 ++ crates/interpreter/src/opcode/eof_printer.rs | 1 - crates/primitives/src/bytecode/eof.rs | 2 +- crates/primitives/src/bytecode/eof/body.rs | 4 +- crates/primitives/src/env.rs | 58 +++++++++- crates/primitives/src/env/handler_cfg.rs | 4 +- crates/primitives/src/result.rs | 12 +++ crates/revm/src/context/inner_evm_context.rs | 2 +- crates/revm/src/inspector/eip3155.rs | 1 - 14 files changed, 183 insertions(+), 48 deletions(-) diff --git a/crates/interpreter/src/call_inputs.rs b/crates/interpreter/src/call_inputs.rs index e16459496f..5f9cb32abf 100644 --- a/crates/interpreter/src/call_inputs.rs +++ b/crates/interpreter/src/call_inputs.rs @@ -17,17 +17,16 @@ pub struct CallInputs { pub bytecode_address: Address, /// Target address, this account storage is going to be modified. pub target_address: Address, - /// This caller that is invoking this call. + /// This caller is invoking the call. pub caller: Address, - /// Value is Ether that is transferred. + /// 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. - /// This is used by delegate call. + /// 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. + /// The scheme used for the call. Call, callcode, delegatecall or staticcall. pub scheme: CallScheme, /// Whether this is a static call. pub is_static: bool, diff --git a/crates/interpreter/src/eof_create_inputs.rs b/crates/interpreter/src/eof_create_inputs.rs index 875b3bce08..60a097bb7b 100644 --- a/crates/interpreter/src/eof_create_inputs.rs +++ b/crates/interpreter/src/eof_create_inputs.rs @@ -1,7 +1,7 @@ use crate::primitives::{Address, Eof, U256}; use core::ops::Range; -/// Inputs for create call. +/// Inputs for EOF create call. #[derive(Debug, Default, Clone)] pub struct EOFCreateInput { /// Caller of Eof Craate diff --git a/crates/interpreter/src/host.rs b/crates/interpreter/src/host.rs index d4cc9e357b..49ffbd02a6 100644 --- a/crates/interpreter/src/host.rs +++ b/crates/interpreter/src/host.rs @@ -63,6 +63,7 @@ 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 @@ -71,7 +72,7 @@ pub struct LoadAccountResult { pub is_empty: bool, } -/// Result of a call that resulted in a self destruct. +/// Result of a selfdestruct instruction. #[derive(Default, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SelfDestructResult { diff --git a/crates/interpreter/src/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index 1865e35b52..5a88b817f5 100644 --- a/crates/interpreter/src/instruction_result.rs +++ b/crates/interpreter/src/instruction_result.rs @@ -45,12 +45,13 @@ pub enum InstructionResult { CreateContractStartingWithEF, /// EIP-3860: Limit and meter initcode. Initcode size limit exceeded. CreateInitCodeSizeLimit, - /* External error */ /// Fatal external error. Returned by database. FatalExternalError, /// Opcode called that are not found in EOF. /// This should not happen if the bytecode is validated correctly. OpcodeDisabledInEof, + /// RETURNCONTRACT called in not init eof code. + ReturnContractInNotInitEOF, /// Legacy contract is calling opcode that is enabled only in EOF. EOFOpcodeDisabledInLegacy, /// EOF function stack overflow @@ -147,6 +148,7 @@ macro_rules! return_error { | InstructionResult::CreateInitCodeSizeLimit | InstructionResult::FatalExternalError | InstructionResult::OpcodeDisabledInEof + | InstructionResult::ReturnContractInNotInitEOF | InstructionResult::EOFOpcodeDisabledInLegacy | InstructionResult::EOFFunctionStackOverflow | InstructionResult::EOFCodeIdxOutOfBounds @@ -231,8 +233,6 @@ impl From for SuccessOrHalt { InstructionResult::Return => Self::Success(SuccessReason::Return), InstructionResult::SelfDestruct => Self::Success(SuccessReason::SelfDestruct), InstructionResult::Revert => Self::Revert, - // TODO EOFCreate is not external opcode. - InstructionResult::ReturnContract => Self::FatalExternalError, InstructionResult::CallOrCreate => Self::InternalCallOrCreate, // used only in interpreter loop InstructionResult::CallTooDeep => Self::Halt(HaltReason::CallTooDeep), // not gonna happen for first call InstructionResult::OutOfFunds => Self::Halt(HaltReason::OutOfFunds), // Check for first call is done separately. @@ -272,14 +272,14 @@ impl From for SuccessOrHalt { Self::Halt(HaltReason::CreateInitCodeSizeLimit) } InstructionResult::FatalExternalError => Self::FatalExternalError, - // TODO(EOF) Check how to propagate error that should be a EVM panic! - InstructionResult::OpcodeDisabledInEof => Self::FatalExternalError, - // TODO(EOF) make proper error InstructionResult::EOFOpcodeDisabledInLegacy => Self::Halt(HaltReason::OpcodeNotFound), - // TODO(EOF) InstructionResult::EOFFunctionStackOverflow => Self::FatalExternalError, - // TODO(EOF) - InstructionResult::EOFCodeIdxOutOfBounds => Self::FatalExternalError, + flag @ (InstructionResult::ReturnContract + | InstructionResult::EOFCodeIdxOutOfBounds + | InstructionResult::OpcodeDisabledInEof + | InstructionResult::ReturnContractInNotInitEOF) => { + panic!("Unexpected internal return flag: {:?}", flag) + } } } } diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 5ec88ea9e7..8d96376677 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -6,15 +6,20 @@ pub use call_helpers::{ 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, InterpreterAction}, primitives::{Address, Bytes, Eof, Spec, SpecId::*, B256, U256}, CallInputs, CallScheme, CreateInputs, CreateScheme, EOFCreateInput, Host, InstructionResult, - LoadAccountResult, TransferValue, MAX_INITCODE_SIZE, + 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, @@ -32,6 +37,7 @@ pub fn resize_memory( } } +/// EOF Create instruction pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, EOF_CREATE_GAS); @@ -46,8 +52,9 @@ pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) .get(initcontainer_index as usize) .cloned() else { - // TODO(EOF) handle error - interpreter.instruction_result = InstructionResult::FatalExternalError; + // Container idx bound is checked in verification. + // This is training wheel that should be removed in future. + interpreter.instruction_result = InstructionResult::EOFCodeIdxOutOfBounds; return; }; @@ -89,7 +96,7 @@ pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; } -pub fn txcreate(interpreter: &mut Interpreter, _host: &mut H) { +pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, EOF_CREATE_GAS); pop!( @@ -100,20 +107,28 @@ pub fn txcreate(interpreter: &mut Interpreter, _host: &mut H) data_offset, data_size ); - // TODO(EOF) check when memory resize should be done + 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; }; - let tx_initcode_hash = B256::from(tx_initcode_hash); - - // TODO(EOF) get initcode from TxEnv. - let initcode = Bytes::new(); + // fetch initcode, if not found push ZERO. + let Some(initcode) = host.env().tx.eof_initcodes.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)); - // TODO check if data container is full + // deduct gas for hash. TODO check order of actions. + gas_or_fail!( + interpreter, + cost_per_word::(initcode.len() as u64) + ); + let Ok(eof) = Eof::decode(initcode.clone()) else { push!(interpreter, U256::ZERO); return; @@ -125,13 +140,11 @@ pub fn txcreate(interpreter: &mut Interpreter, _host: &mut H) return; } - // TODO(EOF) validate initcode, we should do this only once and cache result. - - // deduct gas for hash. - gas_or_fail!( - interpreter, - cost_per_word::(initcode.len() as u64) - ); + // 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 @@ -157,7 +170,60 @@ pub fn txcreate(interpreter: &mut Interpreter, _host: &mut H) } pub fn return_contract(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + 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 Some(container) = interpreter + .eof() + .expect("EOF is set") + .body + .container_section + .get(deploy_container_index as usize) + else { + // TODO(EOF) handle error. Should not happen. + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + // 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.unwrap(), 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 { diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index 6f63f84705..f7a2d8c865 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -22,6 +22,17 @@ macro_rules! error_on_disabled_eof { }; } +/// 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; + } + }; +} + /// Panic if the current call is EOF. Thes macro is training wheel and should be removed once /// EOF is fully implemented. macro_rules! panic_on_eof { diff --git a/crates/interpreter/src/opcode/eof_printer.rs b/crates/interpreter/src/opcode/eof_printer.rs index f72f71b391..7c9990872c 100644 --- a/crates/interpreter/src/opcode/eof_printer.rs +++ b/crates/interpreter/src/opcode/eof_printer.rs @@ -31,7 +31,6 @@ pub fn print_eof_code(code: &[u8]) { hex::encode(&code[i + 1..i + 1 + opcode.immediate_size as usize]) ); } - println!(""); let mut rjumpv_additional_immediates = 0; if op == RJUMPV { diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index 6f61003b0f..19e0fb0dae 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -52,7 +52,7 @@ impl Eof { /// Re-encode the raw EOF bytes. pub fn reencode_inner(&mut self) { - self.raw = Some(self.encode_slow().into()) + self.raw = Some(self.encode_slow()) } /// Slow encode EOF bytes. diff --git a/crates/primitives/src/bytecode/eof/body.rs b/crates/primitives/src/bytecode/eof/body.rs index 6986244bde..f70fa27c9b 100644 --- a/crates/primitives/src/bytecode/eof/body.rs +++ b/crates/primitives/src/bytecode/eof/body.rs @@ -24,11 +24,11 @@ impl EofBody { } for code_section in &self.code_section { - buffer.extend_from_slice(&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(container_section); } buffer.extend_from_slice(&self.data_section); diff --git a/crates/primitives/src/env.rs b/crates/primitives/src/env.rs index ffa8206f35..f8ea6826e5 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,38 @@ 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 !self.tx.eof_initcodes.is_empty() { + return Err(InvalidTransaction::EofInitcodesNotSupported); + } + if self.tx.eof_initcodes.len() > 256 { + return Err(InvalidTransaction::EofInitcodesNumberLimit); + } + if self + .tx + .eof_initcodes + .iter() + .any(|(_, i)| i.len() >= MAX_INITCODE_SIZE) + { + return Err(InvalidTransaction::EofInitcodesSizeLimit); + } + } + Ok(()) } @@ -247,7 +280,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 +516,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 +572,25 @@ 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: HashMap, + #[cfg_attr(feature = "serde", serde(flatten))] #[cfg(feature = "optimism")] 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 +622,7 @@ impl Default for TxEnv { access_list: Vec::new(), blob_hashes: Vec::new(), max_fee_per_blob_gas: None, + eof_initcodes: HashMap::new(), #[cfg(feature = "optimism")] optimism: OptimismFields::default(), } 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/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/revm/src/context/inner_evm_context.rs b/crates/revm/src/context/inner_evm_context.rs index f6ec6a299f..8681f2b9d8 100644 --- a/crates/revm/src/context/inner_evm_context.rs +++ b/crates/revm/src/context/inner_evm_context.rs @@ -318,7 +318,7 @@ impl InnerEvmContext { // commit changes reduces depth by -1. self.journaled_state.checkpoint_commit(); - // decode bytecode is fast operation. + // decode bytecode has a performance hit, but it has reasonable restrains. let bytecode = Eof::decode(interpreter_result.output.clone()).expect("Eof is already verified"); diff --git a/crates/revm/src/inspector/eip3155.rs b/crates/revm/src/inspector/eip3155.rs index 22438fdb7b..cbc4b81734 100644 --- a/crates/revm/src/inspector/eip3155.rs +++ b/crates/revm/src/inspector/eip3155.rs @@ -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()), }; From 761aa2ba04f86fcfcbdb697cb47b12ed8f7bcc40 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 04:56:52 +0200 Subject: [PATCH 40/54] remove training wheels, panic on eof --- crates/interpreter/src/instruction_result.rs | 6 +++++- crates/interpreter/src/instructions/contract.rs | 4 ++-- crates/interpreter/src/instructions/macros.rs | 11 ----------- crates/primitives/src/bytecode/eof.rs | 7 ------- 4 files changed, 7 insertions(+), 21 deletions(-) diff --git a/crates/interpreter/src/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index 5a88b817f5..7f24781df9 100644 --- a/crates/interpreter/src/instruction_result.rs +++ b/crates/interpreter/src/instruction_result.rs @@ -58,6 +58,8 @@ pub enum InstructionResult { EOFFunctionStackOverflow, /// EOF idx is out of bounds EOFCodeIdxOutOfBounds, + /// Eof container idx is out of bounds + EOFCOntainerOutOfBounds, } impl From for InstructionResult { @@ -152,6 +154,7 @@ macro_rules! return_error { | InstructionResult::EOFOpcodeDisabledInLegacy | InstructionResult::EOFFunctionStackOverflow | InstructionResult::EOFCodeIdxOutOfBounds + | InstructionResult::EOFCOntainerOutOfBounds }; } @@ -277,7 +280,8 @@ impl From for SuccessOrHalt { flag @ (InstructionResult::ReturnContract | InstructionResult::EOFCodeIdxOutOfBounds | InstructionResult::OpcodeDisabledInEof - | InstructionResult::ReturnContractInNotInitEOF) => { + | InstructionResult::ReturnContractInNotInitEOF + | InstructionResult::EOFCOntainerOutOfBounds) => { panic!("Unexpected internal return flag: {:?}", flag) } } diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 8d96376677..e0a5953096 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -182,8 +182,8 @@ pub fn return_contract(interpreter: &mut Interpreter, _host: & .container_section .get(deploy_container_index as usize) else { - // TODO(EOF) handle error. Should not happen. - interpreter.instruction_result = InstructionResult::FatalExternalError; + // training wheel that should be removed in future. + interpreter.instruction_result = InstructionResult::EOFCOntainerOutOfBounds; return; }; // convert to EOF so we can check data section size. diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index f7a2d8c865..a610c0db04 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -33,17 +33,6 @@ macro_rules! error_on_not_init_eof { }; } -/// Panic if the current call is EOF. Thes macro is training wheel and should be removed once -/// EOF is fully implemented. -macro_rules! panic_on_eof { - ($interp:expr) => { - if $interp.is_eof { - $interp.instruction_result = $crate::InstructionResult::OpcodeDisabledInEof; - return; - } - }; -} - /// Check if the `SPEC` is enabled, and fail the instruction if it is not. #[macro_export] macro_rules! check { diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index 19e0fb0dae..fc8763bb55 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -81,13 +81,6 @@ impl Eof { raw: Some(raw), }) } - - /// TODO implement it. - pub fn push_aux_data(&mut self, _aux_data: Bytes) { - // Need to modify/replace raw Bytes, and recalculate body sections. - // We can be little wasteful here and just replace the raw Bytes and - // data section in the body. Other sections would still pin old raw Bytes. - } } /// EOF decode errors. From efa73272eb0ec266231a54f60accb63ac85e1416 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 05:39:36 +0200 Subject: [PATCH 41/54] test fix and std --- crates/interpreter/src/opcode.rs | 2 ++ crates/interpreter/tests/eof.rs | 2 +- crates/primitives/src/bytecode/eof.rs | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index a3301b3a78..f900a31f28 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -728,6 +728,8 @@ mod tests { SELFDESTRUCT, RETURNCONTRACT, STOP, + RJUMP, + JUMPF, ]; let mut opcodes = [false; 256]; for terminating in terminating.iter() { diff --git a/crates/interpreter/tests/eof.rs b/crates/interpreter/tests/eof.rs index bd4b2cb933..84bfc347ff 100644 --- a/crates/interpreter/tests/eof.rs +++ b/crates/interpreter/tests/eof.rs @@ -126,7 +126,7 @@ pub fn run_test(path: &Path) { *types_of_error .entry( res.err() - .map(|i| ErrorType::Error(i)) + .map(ErrorType::Error) .unwrap_or(ErrorType::FalsePositive), ) .or_default() += 1; diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index fc8763bb55..2a9265a126 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -9,6 +9,7 @@ pub use types_section::TypesSection; use crate::Bytes; use core::cmp::min; +use std::vec::Vec; #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] From 691ad440e0d05a6cc7c4b2f9bdbb6b5616e27572 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 05:42:21 +0200 Subject: [PATCH 42/54] std --- crates/primitives/src/bytecode/eof/types_section.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs index dc7cc198e5..37bed71516 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -2,6 +2,7 @@ use super::{ decode_helpers::{consume_u16, consume_u8}, EofDecodeError, }; +use std::vec::Vec; /// TODO(EOF) Chekc if max_stack_size >= inputs. #[derive(Debug, Clone, Default, Hash, PartialEq, Eq, Copy)] From 8faa75aacd989190309dac702188412dd17bb014 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 05:46:35 +0200 Subject: [PATCH 43/54] fix test --- crates/interpreter/src/instructions/system.rs | 2 +- crates/interpreter/src/interpreter/analysis.rs | 6 ++++-- crates/interpreter/src/interpreter/contract.rs | 2 +- crates/primitives/src/bytecode/eof/types_section.rs | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index 832e1ff3e5..996b959ec0 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -133,7 +133,7 @@ pub fn returndatacopy(interpreter: &mut Interprete } } -/// Part of EOF https://eips.ethereum.org/EIPS/eip-7069 +/// Part of EOF ``. pub fn returndataload(interpreter: &mut Interpreter, _host: &mut H) { error_on_disabled_eof!(interpreter); gas!(interpreter, gas::VERYLOW); diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 62fc244829..663f7238fa 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -176,7 +176,7 @@ pub enum EofValidationError { InstructionNotForwardAccessed, /// Bytecode is too small and is missing immediate bytes for instruction. MissingImmediateBytes, - /// Similar to [`MissingImmediateBytes`] but for special case of RJUMPV immediate bytes. + /// Similar to [`EofValidationError::MissingImmediateBytes`] but for special case of RJUMPV immediate bytes. MissingRJUMPVImmediateBytes, /// Invalid jump into immediate bytes. JumpToImmediateBytes, @@ -609,7 +609,9 @@ mod test { validate_raw_eof(hex!("ef000101000c02000300040008000304000000008000020002000503010003e30001005f5f5f5f5fe500025050e4").into()); assert_eq!( err, - Err(EofError::Validation(EofValidationError::JUMPFEnoughOutputs)) + Err(EofError::Validation( + EofValidationError::JUMPFStackHigherThanOutputs + )) ); } } diff --git a/crates/interpreter/src/interpreter/contract.rs b/crates/interpreter/src/interpreter/contract.rs index 966dd2051b..5959c7cfed 100644 --- a/crates/interpreter/src/interpreter/contract.rs +++ b/crates/interpreter/src/interpreter/contract.rs @@ -62,7 +62,7 @@ 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, diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs index 37bed71516..ae997cabb8 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -11,7 +11,7 @@ pub struct TypesSection { /// inputs - 1 byte - `0x00-0x7F` /// number of stack elements the code section consumes pub inputs: u8, - /// outputs - 1 byte - `0x00-0x80`` + /// 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` From 4af1988170cfd74820bb2a2537f2025daaa25b11 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 05:51:47 +0200 Subject: [PATCH 44/54] fix valgrind --- .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 c337cd900899671baa701945049622bbd347b1f5 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 06:00:33 +0200 Subject: [PATCH 45/54] fix tests --- bins/revme/src/cmd/bytecode.rs | 2 +- crates/interpreter/src/opcode.rs | 17 ++++++----------- crates/primitives/src/bytecode/eof/header.rs | 2 +- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/bins/revme/src/cmd/bytecode.rs b/bins/revme/src/cmd/bytecode.rs index 9ffc5352c5..9bc8a92e15 100644 --- a/bins/revme/src/cmd/bytecode.rs +++ b/bins/revme/src/cmd/bytecode.rs @@ -17,7 +17,7 @@ impl Cmd { /// Run statetest command. pub fn run(&self) { let trimmed = self.bytes.trim_start_matches("0x"); - let Ok(bytes) = hex::decode(&trimmed) else { + let Ok(bytes) = hex::decode(trimmed) else { eprintln!("Invalid hex string"); return; }; diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index f900a31f28..401c7c378e 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -648,9 +648,9 @@ mod tests { #[test] fn test_opcode() { let opcode = OpCode::new(0x00).unwrap(); - assert_eq!(opcode.is_jumpdest(), false); - assert_eq!(opcode.is_jump(), false); - assert_eq!(opcode.is_push(), false); + assert!(!opcode.is_jumpdest()); + assert!(!opcode.is_jump()); + assert!(!opcode.is_push()); assert_eq!(opcode.as_str(), "STOP"); assert_eq!(opcode.get(), 0x00); } @@ -663,12 +663,7 @@ mod tests { fn test_eof_disable() { for opcode in REJECTED_IN_EOF.iter() { let opcode = OpCode::new(*opcode).unwrap(); - assert_eq!( - opcode.info().is_eof, - false, - "Opcode {:?} is not EOF", - opcode - ); + assert!(!opcode.info().is_eof, "Opcode {:?} is not EOF", opcode); } } @@ -699,7 +694,7 @@ mod tests { 0x30..=0x3f, 0x40..=0x48, 0x50..=0x5b, - 0x5f..=0x54, + 0x54..=0x5f, 0x60..=0x6f, 0x70..=0x7f, 0x80..=0x8f, @@ -736,7 +731,7 @@ mod tests { opcodes[*terminating as usize] = true; } - for (i, opcode) in OPCODE_INFO_JUMPTABLE.clone().into_iter().enumerate() { + for (i, opcode) in OPCODE_INFO_JUMPTABLE.into_iter().enumerate() { assert_eq!( opcode .map(|opcode| opcode.is_terminating_opcode) diff --git a/crates/primitives/src/bytecode/eof/header.rs b/crates/primitives/src/bytecode/eof/header.rs index 78b76755b1..bb2d74d8b7 100644 --- a/crates/primitives/src/bytecode/eof/header.rs +++ b/crates/primitives/src/bytecode/eof/header.rs @@ -243,7 +243,7 @@ mod tests { let mut input = hex!("ef0001010004"); assert_eq!( EofHeader::decode(&mut input), - Err(EofDecodeError::InvalidTerminalByte) + Err(EofDecodeError::MissingInput) ); } From a19865ff12d3c61b9ad441eac30b9083c95b0c53 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 06:08:37 +0200 Subject: [PATCH 46/54] clippy --- crates/primitives/src/bytecode/eof/header.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/crates/primitives/src/bytecode/eof/header.rs b/crates/primitives/src/bytecode/eof/header.rs index bb2d74d8b7..5596b0e2bd 100644 --- a/crates/primitives/src/bytecode/eof/header.rs +++ b/crates/primitives/src/bytecode/eof/header.rs @@ -230,8 +230,8 @@ mod tests { #[test] fn sanity_header_decode() { - let mut input = hex!("ef000101000402000100010400000000800000fe"); - let (header, _) = EofHeader::decode(&mut input).unwrap(); + 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![]); @@ -240,11 +240,8 @@ mod tests { #[test] fn decode_header_not_terminated() { - let mut input = hex!("ef0001010004"); - assert_eq!( - EofHeader::decode(&mut input), - Err(EofDecodeError::MissingInput) - ); + let input = hex!("ef0001010004"); + assert_eq!(EofHeader::decode(&input), Err(EofDecodeError::MissingInput)); } #[test] From 647a8d2e1efce13c61d630772b4f7bfcc1e33ed2 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 06:21:27 +0200 Subject: [PATCH 47/54] removed checked logic --- crates/interpreter/src/instruction_result.rs | 22 +++++-------------- .../interpreter/src/instructions/contract.rs | 18 +++++---------- crates/interpreter/src/instructions/macros.rs | 2 +- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/crates/interpreter/src/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index 7f24781df9..9e0f6e1264 100644 --- a/crates/interpreter/src/instruction_result.rs +++ b/crates/interpreter/src/instruction_result.rs @@ -47,19 +47,12 @@ pub enum InstructionResult { CreateInitCodeSizeLimit, /// Fatal external error. Returned by database. FatalExternalError, - /// Opcode called that are not found in EOF. - /// This should not happen if the bytecode is validated correctly. - OpcodeDisabledInEof, /// 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, - /// EOF idx is out of bounds - EOFCodeIdxOutOfBounds, - /// Eof container idx is out of bounds - EOFCOntainerOutOfBounds, } impl From for InstructionResult { @@ -149,12 +142,9 @@ macro_rules! return_error { | InstructionResult::CreateContractStartingWithEF | InstructionResult::CreateInitCodeSizeLimit | InstructionResult::FatalExternalError - | InstructionResult::OpcodeDisabledInEof | InstructionResult::ReturnContractInNotInitEOF | InstructionResult::EOFOpcodeDisabledInLegacy | InstructionResult::EOFFunctionStackOverflow - | InstructionResult::EOFCodeIdxOutOfBounds - | InstructionResult::EOFCOntainerOutOfBounds }; } @@ -250,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 @@ -277,12 +269,8 @@ impl From for SuccessOrHalt { InstructionResult::FatalExternalError => Self::FatalExternalError, InstructionResult::EOFOpcodeDisabledInLegacy => Self::Halt(HaltReason::OpcodeNotFound), InstructionResult::EOFFunctionStackOverflow => Self::FatalExternalError, - flag @ (InstructionResult::ReturnContract - | InstructionResult::EOFCodeIdxOutOfBounds - | InstructionResult::OpcodeDisabledInEof - | InstructionResult::ReturnContractInNotInitEOF - | InstructionResult::EOFCOntainerOutOfBounds) => { - panic!("Unexpected internal return flag: {:?}", flag) + InstructionResult::ReturnContract => { + panic!("Unexpected EOF internal Return Contract") } } } diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index bae89a547e..0f0526a4c7 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -44,19 +44,14 @@ pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) let initcontainer_index = unsafe { *interpreter.instruction_pointer }; pop!(interpreter, value, salt, data_offset, data_size); - let Some(sub_container) = interpreter + let sub_container = interpreter .eof() .expect("EOF is set") .body .container_section .get(initcontainer_index as usize) .cloned() - else { - // Container idx bound is checked in verification. - // This is training wheel that should be removed in future. - interpreter.instruction_result = InstructionResult::EOFCodeIdxOutOfBounds; - return; - }; + .expect("EOF is checked"); // resize memory and get return range. let Some(return_range) = resize_memory(interpreter, data_offset, data_size) else { @@ -175,17 +170,14 @@ pub fn return_contract(interpreter: &mut Interpreter, _host: & 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 Some(container) = interpreter + let container = interpreter .eof() .expect("EOF is set") .body .container_section .get(deploy_container_index as usize) - else { - // training wheel that should be removed in future. - interpreter.instruction_result = InstructionResult::EOFCOntainerOutOfBounds; - return; - }; + .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"); diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index a610c0db04..a50dddfcb4 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -26,7 +26,7 @@ macro_rules! error_on_disabled_eof { #[macro_export] macro_rules! error_on_not_init_eof { ($interp:expr) => { - if $interp.is_eof_init { + if !$interp.is_eof_init { $interp.instruction_result = $crate::InstructionResult::ReturnContractInNotInitEOF; return; } From 98745cc57cb4f704ef711ab9b7a37fea5a664901 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 14:17:32 +0200 Subject: [PATCH 48/54] small change --- crates/interpreter/src/gas.rs | 2 +- crates/interpreter/src/interpreter.rs | 2 +- crates/interpreter/src/interpreter/stack.rs | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) 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/interpreter.rs b/crates/interpreter/src/interpreter.rs index 3cf29b1353..c3fd1cc2bb 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -383,7 +383,7 @@ impl Interpreter { /// Executes the instruction at the current instruction pointer. /// /// Internally it will increment instruction pointer by one. - #[inline(always)] + #[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/stack.rs b/crates/interpreter/src/interpreter/stack.rs index 92a5c0db2b..1a85f4f722 100644 --- a/crates/interpreter/src/interpreter/stack.rs +++ b/crates/interpreter/src/interpreter/stack.rs @@ -232,10 +232,9 @@ impl Stack { } 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(()) } } From 65cf05c5dc9b4a7ccfd017098be425032371dff9 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 15:07:31 +0200 Subject: [PATCH 49/54] no std revm-test --- bins/revm-test/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bins/revm-test/Cargo.toml b/bins/revm-test/Cargo.toml index 527efff315..7605826a1d 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, features=["std"] } +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" From 8162f3242832537f4cb21287f571ecca4c787ed5 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 20:22:16 +0200 Subject: [PATCH 50/54] check pending TODOs --- crates/interpreter/src/gas/calc.rs | 35 ++++++-------- .../interpreter/src/instructions/contract.rs | 2 +- crates/interpreter/src/instructions/host.rs | 6 ++- crates/interpreter/src/interpreter.rs | 1 - .../interpreter/src/interpreter/analysis.rs | 18 +------ crates/interpreter/src/opcode/eof_printer.rs | 5 -- crates/primitives/src/bytecode.rs | 2 +- crates/primitives/src/bytecode/eof.rs | 48 +++++++++---------- crates/primitives/src/bytecode/eof/body.rs | 34 ++++++++++++- .../src/bytecode/eof/decode_helpers.rs | 1 + crates/primitives/src/bytecode/eof/header.rs | 7 ++- .../src/bytecode/eof/types_section.rs | 9 +++- crates/primitives/src/bytecode/legacy.rs | 9 ++++ .../src/bytecode/legacy/jump_map.rs | 2 +- crates/revm/src/context/inner_evm_context.rs | 3 +- 15 files changed, 104 insertions(+), 78 deletions(-) diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index 5f7f562b2a..214f794b00 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -78,11 +78,10 @@ pub const fn create2_cost(len: u64) -> Option { } #[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 { @@ -93,6 +92,10 @@ fn log2floor(value: U256) -> u64 { return l - 1; } } + if i == 0 { + break; + } + i -= 1; } l } @@ -126,11 +129,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 { @@ -139,27 +138,19 @@ pub const fn extcodecopy_cost(spec_id: SpecId, len: u64, is_cold: bool) -> Optio base_gas.checked_add(tri!(cost_per_word(len, COPY))) } -#[inline] -pub const fn account_access_gas(spec_id: SpecId, is_cold: bool) -> u64 { - if spec_id.is_enabled_in(SpecId::BERLIN) { - warm_cold_cost(is_cold) - } 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 { tri!(LOG.checked_add(tri!(LOGDATA.checked_mul(len)))).checked_add(LOGTOPIC * n as u64) } +/// `KECCAK256` opcode cost calculation. #[inline] pub const fn keccak256_cost(len: u64) -> Option { KECCAK256.checked_add(tri!(cost_per_word(len, KECCAK256WORD))) } +/// 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)) @@ -198,6 +189,7 @@ pub const fn sload_cost(spec_id: SpecId, is_cold: bool) -> u64 { } } +/// `SSTORE` opcode cost calculation. #[inline] pub fn sstore_cost( spec_id: SpecId, @@ -261,6 +253,7 @@ fn frontier_sstore_cost(current: U256, new: U256) -> 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) @@ -337,6 +330,7 @@ pub const fn call_cost( 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 { @@ -346,6 +340,7 @@ pub const fn warm_cold_cost(is_cold: bool) -> u64 { } } +/// Memory expansion cost calculation. #[inline] pub const fn memory_gas(a: usize) -> u64 { let a = a as u64; diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 0f0526a4c7..b390416086 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -205,7 +205,7 @@ pub fn return_contract(interpreter: &mut Interpreter, _host: & } // append data bytes - let output = [&new_eof.raw.unwrap(), aux_slice].concat().into(); + let output = [new_eof.raw(), aux_slice].concat().into(); let result = InstructionResult::ReturnContract; interpreter.instruction_result = result; diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index bc985a9872..10de31606b 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -16,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 { diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index c3fd1cc2bb..df90332750 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -276,7 +276,6 @@ impl Interpreter { self.gas.erase_cost(create_outcome.gas().remaining()); self.gas.record_refund(create_outcome.gas().refunded()); } - // TODO(EOF) check what do to with Depth call and out of fund errors. return_revert!() => { push!(self, U256::ZERO); self.gas.erase_cost(create_outcome.gas().remaining()); diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 663f7238fa..176db35496 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -200,7 +200,7 @@ pub enum EofValidationError { JUMPFStackHigherThanOutputs, /// DATA load out of bounds. DataLoadOutOfBounds, - /// TODO(EOF) check this error. + /// RETF biggest stack num more then outputs. RETFBiggestStackNumMoreThenOutputs, /// Stack requirement is more than smallest stack items. StackUnderflow, @@ -358,11 +358,6 @@ pub fn validate_eof_code( match op { opcode::RJUMP | opcode::RJUMPI => { let offset = unsafe { read_i16(code.as_ptr().add(i + 1)) } as isize; - // TODO(EOF) temporarily disabled for tests - // if offset == 0 { - // // jump immediate instruction is not allowed. - // return Err(EofValidationError::JumpToImmediateBytes); - // } absolute_jumpdest = vec![offset + 3 + i as isize]; // RJUMP is considered a terminating opcode. } @@ -373,12 +368,6 @@ pub fn validate_eof_code( // and max_index+1 is to get size of vtable as index starts from 0. rjumpv_additional_immediates = len * 2; - // Max index can't be zero as it becomes RJUMPI. - // TODO(EOF) temporarily disabled this - // if max_index == 0 { - // return Err(EofValidationError::RJUMPVZeroMaxIndex); - // } - // +1 is for max_index byte if i + 1 + rjumpv_additional_immediates >= code.len() { // Malfunctional code RJUMPV vtable is not complete @@ -395,11 +384,6 @@ pub fn validate_eof_code( for vtablei in 0..len { let offset = unsafe { read_i16(code.as_ptr().add(i + 2 + 2 * vtablei)) } as isize; - // TODO(EOF) temporarily disabled for tests - // if offset == 0 { - // // jump immediate instruction is not allowed. - // return Err(EofValidationError::JumpZeroOffset); - // } jumps.push(offset + i as isize + 2 + rjumpv_additional_immediates as isize); } absolute_jumpdest = jumps diff --git a/crates/interpreter/src/opcode/eof_printer.rs b/crates/interpreter/src/opcode/eof_printer.rs index 7c9990872c..4f326e3cce 100644 --- a/crates/interpreter/src/opcode/eof_printer.rs +++ b/crates/interpreter/src/opcode/eof_printer.rs @@ -47,11 +47,6 @@ pub fn print_eof_code(code: &[u8]) { for vtablei in 0..len { let offset = unsafe { read_i16(code.as_ptr().add(i + 2 + 2 * vtablei)) } as isize; - // TODO(EOF) for now disable checks for testing. - // if offset == 0 { - // println!("Malformed code: zero offset in RJUMPV"); - // } - println!("RJUMPV[{vtablei}]: 0x{offset:04X}({offset})"); } } diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index 4605e2c888..64c9f986bf 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -114,7 +114,7 @@ impl Bytecode { match self { Self::LegacyRaw(bytes) => bytes.clone(), Self::LegacyAnalyzed(analyzed) => analyzed.original_bytes(), - Self::Eof(eof) => eof.raw().expect("TODO see if we should remove Option"), + Self::Eof(eof) => eof.raw().clone(), } } diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index 2a9265a126..5544ee501b 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -11,18 +11,33 @@ use crate::Bytes; use core::cmp::min; use std::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: Option, + pub raw: Bytes, } impl Default for Eof { fn default() -> Self { - // TODO(EOF) make proper minimal EOF. - Eof::decode("ef000101000402000100010400000000800000fe".into()).unwrap() + 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() } } @@ -32,8 +47,9 @@ impl Eof { self.header.size() + self.header.body_size() } - pub fn raw(&self) -> Option { - self.raw.clone() + /// Return raw EOF bytes. + pub fn raw(&self) -> &Bytes { + &self.raw } /// Returns a slice of the raw bytes. @@ -47,15 +63,11 @@ impl Eof { .unwrap_or(&[]) } + /// Returns a slice of the data section. pub fn data(&self) -> &[u8] { &self.body.data_section } - /// Re-encode the raw EOF bytes. - pub fn reencode_inner(&mut self) { - self.raw = Some(self.encode_slow()) - } - /// Slow encode EOF bytes. pub fn encode_slow(&self) -> Bytes { let mut buffer: Vec = Vec::with_capacity(self.size()); @@ -64,23 +76,11 @@ impl Eof { buffer.into() } - /// Encode the EOF into bytes. - pub fn encode(&self) -> Bytes { - if let Some(raw) = &self.raw { - raw.clone() - } else { - self.encode_slow() - } - } - + /// 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: Some(raw), - }) + Ok(Self { header, body, raw }) } } diff --git a/crates/primitives/src/bytecode/eof/body.rs b/crates/primitives/src/bytecode/eof/body.rs index f70fa27c9b..3759372b8a 100644 --- a/crates/primitives/src/bytecode/eof/body.rs +++ b/crates/primitives/src/bytecode/eof/body.rs @@ -1,7 +1,10 @@ -use super::{EofDecodeError, EofHeader, TypesSection}; +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 { @@ -18,6 +21,32 @@ impl EofBody { 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); @@ -34,6 +63,7 @@ impl EofBody { 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 = @@ -51,7 +81,7 @@ impl EofBody { let mut body = EofBody::default(); let mut types_input = &input[header_len..]; - for _ in 0..header.types_items() { + 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); diff --git a/crates/primitives/src/bytecode/eof/decode_helpers.rs b/crates/primitives/src/bytecode/eof/decode_helpers.rs index 50ebaf6bb9..d2d2eb555d 100644 --- a/crates/primitives/src/bytecode/eof/decode_helpers.rs +++ b/crates/primitives/src/bytecode/eof/decode_helpers.rs @@ -1,5 +1,6 @@ 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() { diff --git a/crates/primitives/src/bytecode/eof/header.rs b/crates/primitives/src/bytecode/eof/header.rs index 5596b0e2bd..bd7a33d7b7 100644 --- a/crates/primitives/src/bytecode/eof/header.rs +++ b/crates/primitives/src/bytecode/eof/header.rs @@ -83,18 +83,22 @@ impl EofHeader { 13 + self.code_sizes.len() * 2 + optional_container_sizes } - pub fn types_items(&self) -> usize { + /// 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()); @@ -130,6 +134,7 @@ impl 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(); diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs index ae997cabb8..84db61f019 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -4,7 +4,7 @@ use super::{ }; use std::vec::Vec; -/// TODO(EOF) Chekc if max_stack_size >= inputs. +/// 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 { @@ -26,12 +26,15 @@ impl TypesSection { 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)?; @@ -46,10 +49,14 @@ impl TypesSection { 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 index 47fbd23849..18949f0aa6 100644 --- a/crates/primitives/src/bytecode/legacy.rs +++ b/crates/primitives/src/bytecode/legacy.rs @@ -10,8 +10,11 @@ use std::sync::Arc; #[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, } @@ -36,18 +39,24 @@ impl LegacyAnalyzedBytecode { } } + /// 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 index 89371b50f7..af86178775 100644 --- a/crates/primitives/src/bytecode/legacy/jump_map.rs +++ b/crates/primitives/src/bytecode/legacy/jump_map.rs @@ -22,7 +22,7 @@ impl JumpTable { self.0.as_raw_slice() } - /// Construct a jumpa map from raw bytes + /// Construct a jump map from raw bytes #[inline] pub fn from_slice(slice: &[u8]) -> Self { Self(Arc::new(BitVec::from_slice(slice))) diff --git a/crates/revm/src/context/inner_evm_context.rs b/crates/revm/src/context/inner_evm_context.rs index e46c000ecc..63e1146721 100644 --- a/crates/revm/src/context/inner_evm_context.rs +++ b/crates/revm/src/context/inner_evm_context.rs @@ -243,7 +243,6 @@ impl InnerEvmContext { }; // Check depth - // TODO(EOF) what to do on system error is still discussed. if self.journaled_state.depth() > CALL_STACK_LIMIT { return return_error(InstructionResult::CallTooDeep); } @@ -327,7 +326,7 @@ impl InnerEvmContext { let bytecode = Eof::decode(interpreter_result.output.clone()).expect("Eof is already verified"); - // TODO(EOF) should we do keccak256 over bytes? + // eof bytecode is going to be hashed. self.journaled_state .set_code(address, Bytecode::Eof(bytecode)); } From 0222cc0acb05346e9cc511a709141376dce16a99 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 20:32:53 +0200 Subject: [PATCH 51/54] build check no_std --- crates/interpreter/src/opcode/eof_printer.rs | 9 +++++---- crates/primitives/src/bytecode/eof.rs | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/interpreter/src/opcode/eof_printer.rs b/crates/interpreter/src/opcode/eof_printer.rs index 4f326e3cce..d593d9a7fa 100644 --- a/crates/interpreter/src/opcode/eof_printer.rs +++ b/crates/interpreter/src/opcode/eof_printer.rs @@ -1,9 +1,9 @@ -use self::utility::read_i16; -use super::*; -use revm_primitives::hex; - #[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() { @@ -58,6 +58,7 @@ pub fn print_eof_code(code: &[u8]) { #[cfg(test)] mod test { use super::*; + use revm_primitives::hex; #[test] fn sanity_test() { diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index 5544ee501b..d63056b3e5 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -9,7 +9,7 @@ pub use types_section::TypesSection; use crate::Bytes; use core::cmp::min; -use std::vec::Vec; +use std::{vec, vec::Vec}; /// EOF - Ethereum Object Format. /// From eeeb798fc927a2ffcd636b286f716dbb052f8bdd Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 20:33:26 +0200 Subject: [PATCH 52/54] doc --- crates/primitives/src/bytecode/eof.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs index d63056b3e5..67580c1577 100644 --- a/crates/primitives/src/bytecode/eof.rs +++ b/crates/primitives/src/bytecode/eof.rs @@ -17,7 +17,7 @@ use std::{vec, vec::Vec}; /// 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. +/// 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 { From 4c60857f9b648acd6112bb223e9fd4ad8c223862 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 9 Apr 2024 02:18:14 +0200 Subject: [PATCH 53/54] chore: move some files. cleanup comments --- bins/revm-test/Cargo.toml | 2 +- bins/revme/src/cmd/statetest/runner.rs | 4 +- crates/interpreter/src/function_stack.rs | 3 + crates/interpreter/src/gas/calc.rs | 14 +++- crates/interpreter/src/inner_models.rs | 52 -------------- .../interpreter/src/instructions/contract.rs | 8 ++- .../interpreter/src/interpreter/analysis.rs | 19 ++---- crates/interpreter/src/interpreter/stack.rs | 2 +- crates/interpreter/src/interpreter_action.rs | 67 +++++++++++++++++++ .../{ => interpreter_action}/call_inputs.rs | 0 .../{ => interpreter_action}/call_outcome.rs | 0 .../{ => interpreter_action}/create_inputs.rs | 0 .../create_outcome.rs | 0 .../eof_create_inputs.rs | 0 .../eof_create_outcome.rs | 7 +- crates/interpreter/src/lib.rs | 20 ++---- crates/primitives/src/bytecode.rs | 2 +- crates/primitives/src/env.rs | 38 +++++++---- crates/revm/src/handler/mainnet/validation.rs | 3 +- 19 files changed, 135 insertions(+), 106 deletions(-) delete mode 100644 crates/interpreter/src/inner_models.rs create mode 100644 crates/interpreter/src/interpreter_action.rs rename crates/interpreter/src/{ => interpreter_action}/call_inputs.rs (100%) rename crates/interpreter/src/{ => interpreter_action}/call_outcome.rs (100%) rename crates/interpreter/src/{ => interpreter_action}/create_inputs.rs (100%) rename crates/interpreter/src/{ => interpreter_action}/create_outcome.rs (100%) rename crates/interpreter/src/{ => interpreter_action}/eof_create_inputs.rs (100%) rename crates/interpreter/src/{ => interpreter_action}/eof_create_outcome.rs (90%) diff --git a/bins/revm-test/Cargo.toml b/bins/revm-test/Cargo.toml index 7605826a1d..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/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index 1bfc2c175b..f2a58b6115 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -67,9 +67,7 @@ pub fn find_all_json_tests(path: &Path) -> Vec { fn skip_test(path: &Path) -> bool { let path_str = path.to_str().expect("Path is not valid UTF-8"); let name = path.file_name().unwrap().to_str().unwrap(); - if path_str.contains("stRandom") { - return true; - } + matches!( name, // funky test with `bigint 0x00` value in json :) not possible to happen on mainnet and require diff --git a/crates/interpreter/src/function_stack.rs b/crates/interpreter/src/function_stack.rs index cf2690c913..ef786cd662 100644 --- a/crates/interpreter/src/function_stack.rs +++ b/crates/interpreter/src/function_stack.rs @@ -10,11 +10,13 @@ pub struct FunctionReturnFrame { } 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, @@ -22,6 +24,7 @@ pub struct FunctionStack { } impl FunctionStack { + /// Returns new function stack. pub fn new() -> Self { Self { return_stack: Vec::new(), diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index 214f794b00..18d0fd70bf 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -1,3 +1,5 @@ +use revm_primitives::Bytes; + use super::constants::*; use crate::{ primitives::{ @@ -356,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/inner_models.rs b/crates/interpreter/src/inner_models.rs deleted file mode 100644 index 7bec10611b..0000000000 --- a/crates/interpreter/src/inner_models.rs +++ /dev/null @@ -1,52 +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 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(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), - } - } -} diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index b390416086..b684f7b34a 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -110,7 +110,13 @@ pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) { }; // fetch initcode, if not found push ZERO. - let Some(initcode) = host.env().tx.eof_initcodes.get(&tx_initcode_hash).cloned() else { + let Some(initcode) = host + .env() + .tx + .eof_initcodes_hashed + .get(&tx_initcode_hash) + .cloned() + else { push!(interpreter, U256::ZERO); return; }; diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 176db35496..bc2d96d2f5 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -73,13 +73,8 @@ pub fn validate_raw_eof(bytecode: Bytes) -> Result { } /// Validate Eof structures. -/// -/// do perf test on: -/// max eof containers -/// max depth of containers. -/// bytecode iteration. pub fn validate_eof(eof: &Eof) -> Result<(), EofError> { - // clone is cheat as it is Bytes and a header. + // clone is cheap as it is Bytes and a header. let mut queue = vec![eof.clone()]; while let Some(eof) = queue.pop() { @@ -316,8 +311,6 @@ pub fn validate_eof_code( let this_instruction = &mut jumps[i]; - //println!("next b: {next_biggest}, next s: {next_smallest} terminal: {is_after_termination} opcode: {}",opcode.name); - // 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); @@ -497,10 +490,9 @@ pub fn validate_eof_code( return Err(EofValidationError::StackUnderflow); } - //println!("stack_io_diff: {}", stack_io_diff); next_smallest = this_instruction.smallest + stack_io_diff; next_biggest = this_instruction.biggest + stack_io_diff; - //println!("absolute_jumpdest: {absolute_jumpdest:?}"); + // check if jumpdest are correct and mark forward jumps. for absolute_jump in absolute_jumpdest { if absolute_jump < 0 { @@ -524,7 +516,6 @@ pub fn validate_eof_code( target_jump.is_jumpdest = true; if absolute_jump <= i { - //println!("JUMP: {i} -> {target_jump:?}"); // backward jumps should have same smallest and biggest stack items. if target_jump.biggest != next_biggest { // wrong jumpdest. @@ -572,7 +563,7 @@ mod test { #[test] fn test1() { - //result:Result { result: false, exception: Some("EOF_ConflictingStackHeight") } + // result:Result { result: false, exception: Some("EOF_ConflictingStackHeight") } let err = validate_raw_eof(hex!("ef0001010004020001000704000000008000016000e200fffc00").into()); assert!(err.is_err(), "{err:#?}"); @@ -580,7 +571,7 @@ mod test { #[test] fn test2() { - //result:Result { result: false, exception: Some("EOF_InvalidNumberOfOutputs") } + // result:Result { result: false, exception: Some("EOF_InvalidNumberOfOutputs") } let err = validate_raw_eof(hex!("ef000101000c02000300040004000204000000008000020002000100010001e30001005fe500025fe4").into()); assert!(err.is_ok(), "{err:#?}"); @@ -588,7 +579,7 @@ mod test { #[test] fn test3() { - //result:Result { result: false, exception: Some("EOF_InvalidNumberOfOutputs") } + // result:Result { result: false, exception: Some("EOF_InvalidNumberOfOutputs") } let err = validate_raw_eof(hex!("ef000101000c02000300040008000304000000008000020002000503010003e30001005f5f5f5f5fe500025050e4").into()); assert_eq!( diff --git a/crates/interpreter/src/interpreter/stack.rs b/crates/interpreter/src/interpreter/stack.rs index ec0ca19d8d..44dbb48a64 100644 --- a/crates/interpreter/src/interpreter/stack.rs +++ b/crates/interpreter/src/interpreter/stack.rs @@ -171,7 +171,7 @@ impl Stack { (pop1, pop2, pop3, pop4) } - /// Pops 4 values from the stack. + /// Pops 5 values from the stack. /// /// # Safety /// 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/call_inputs.rs b/crates/interpreter/src/interpreter_action/call_inputs.rs similarity index 100% rename from crates/interpreter/src/call_inputs.rs rename to crates/interpreter/src/interpreter_action/call_inputs.rs 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/create_inputs.rs b/crates/interpreter/src/interpreter_action/create_inputs.rs similarity index 100% rename from crates/interpreter/src/create_inputs.rs rename to crates/interpreter/src/interpreter_action/create_inputs.rs 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/eof_create_inputs.rs b/crates/interpreter/src/interpreter_action/eof_create_inputs.rs similarity index 100% rename from crates/interpreter/src/eof_create_inputs.rs rename to crates/interpreter/src/interpreter_action/eof_create_inputs.rs diff --git a/crates/interpreter/src/eof_create_outcome.rs b/crates/interpreter/src/interpreter_action/eof_create_outcome.rs similarity index 90% rename from crates/interpreter/src/eof_create_outcome.rs rename to crates/interpreter/src/interpreter_action/eof_create_outcome.rs index 754a29e913..031e11803f 100644 --- a/crates/interpreter/src/eof_create_outcome.rs +++ b/crates/interpreter/src/interpreter_action/eof_create_outcome.rs @@ -18,16 +18,17 @@ pub struct EOFCreateOutcome { } impl EOFCreateOutcome { - /// Constructs a new `CreateOutcome`. + /// 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 `CreateOutcome` instance. + /// A new [`EOFCreateOutcome`] instance. pub fn new( result: InterpreterResult, address: Address, @@ -40,7 +41,7 @@ impl EOFCreateOutcome { } } - /// Retrieves a reference to the `InstructionResult` from the `InterpreterResult`. + /// 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 diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index e0dbb6f6e3..bf2a49f314 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -19,37 +19,29 @@ use serde_json as _; #[cfg(test)] use walkdir as _; -mod call_inputs; -mod call_outcome; -mod create_inputs; -mod create_outcome; -mod eof_create_inputs; -mod eof_create_outcome; mod function_stack; pub mod gas; mod host; mod instruction_result; pub mod instructions; pub mod interpreter; +pub mod interpreter_action; pub mod opcode; // Reexport primary types. -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; pub use function_stack::{FunctionReturnFrame, FunctionStack}; pub use gas::Gas; pub use host::{DummyHost, Host, LoadAccountResult, SStoreResult, SelfDestructResult}; pub use instruction_result::*; -pub use opcode::{Instruction, OpCode, OPCODE_INFO_JUMPTABLE}; - pub use interpreter::{ analysis, next_multiple_of_32, Contract, Interpreter, InterpreterAction, InterpreterResult, SharedMemory, Stack, EMPTY_SHARED_MEMORY, STACK_LIMIT, }; +pub use interpreter_action::{ + CallInputs, CallOutcome, CallScheme, CreateInputs, CreateOutcome, CreateScheme, EOFCreateInput, + EOFCreateOutcome, TransferValue, +}; +pub use opcode::{Instruction, OpCode, OPCODE_INFO_JUMPTABLE}; pub use primitives::{MAX_CODE_SIZE, MAX_INITCODE_SIZE}; #[doc(hidden)] diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index 64c9f986bf..538a57af44 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -74,7 +74,7 @@ impl Bytecode { /// /// # Safety /// - /// Bytecode need to end with STOP (0x00) opcode as checked bytecode assumes + /// 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_analyzed( bytecode: Bytes, diff --git a/crates/primitives/src/env.rs b/crates/primitives/src/env.rs index f8ea6826e5..9a4470a912 100644 --- a/crates/primitives/src/env.rs +++ b/crates/primitives/src/env.rs @@ -199,22 +199,25 @@ impl Env { 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); } - if self.tx.eof_initcodes.len() > 256 { - return Err(InvalidTransaction::EofInitcodesNumberLimit); - } - if self - .tx - .eof_initcodes - .iter() - .any(|(_, i)| i.len() >= MAX_INITCODE_SIZE) - { - return Err(InvalidTransaction::EofInitcodesSizeLimit); - } } Ok(()) @@ -577,10 +580,18 @@ pub struct TxEnv { /// Incorporated as part of the Prague upgrade via [EOF] /// /// [EOF]: https://eips.ethereum.org/EIPS/eip-4844 - pub eof_initcodes: HashMap, + 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, } @@ -622,7 +633,8 @@ impl Default for TxEnv { access_list: Vec::new(), blob_hashes: Vec::new(), max_fee_per_blob_gas: None, - eof_initcodes: HashMap::new(), + eof_initcodes: Vec::new(), + eof_initcodes_hashed: HashMap::new(), #[cfg(feature = "optimism")] optimism: OptimismFields::default(), } 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 { From d24dcbb8500e961be1cd4d39ca02323cbde66f0c Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 9 Apr 2024 02:40:29 +0200 Subject: [PATCH 54/54] fix fmt,clippy and compile error --- crates/interpreter/src/instructions/contract.rs | 4 ++-- crates/interpreter/src/interpreter.rs | 5 ++--- crates/interpreter/src/lib.rs | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index b684f7b34a..4d3924be95 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -9,10 +9,10 @@ use crate::{ analysis::validate_eof, gas::{self, cost_per_word, BASE, EOF_CREATE_GAS, KECCAK256WORD}, instructions::utility::read_u16, - interpreter::{Interpreter, InterpreterAction}, + interpreter::Interpreter, primitives::{Address, Bytes, Eof, Spec, SpecId::*, B256, U256}, CallInputs, CallScheme, CreateInputs, CreateScheme, EOFCreateInput, Host, InstructionResult, - InterpreterResult, LoadAccountResult, TransferValue, MAX_INITCODE_SIZE, + InterpreterAction, InterpreterResult, LoadAccountResult, TransferValue, MAX_INITCODE_SIZE, }; use core::{cmp::max, ops::Range}; use std::boxed::Box; diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index e0f5541d30..6d0b6320ef 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -9,13 +9,12 @@ pub use stack::{Stack, STACK_LIMIT}; use crate::EOFCreateOutcome; use crate::{ - primitives::Bytes, push, push_b256, return_ok, return_revert, CallInputs, CallOutcome, - CreateInputs, CreateOutcome, EOFCreateInput, FunctionStack, 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::{Bytecode, Eof, U256}; use std::borrow::ToOwned; -use std::boxed::Box; /// EVM bytecode interpreter. #[derive(Debug)] diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index bf2a49f314..7d749fb9b1 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -34,12 +34,12 @@ 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, 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, TransferValue, + EOFCreateOutcome, InterpreterAction, TransferValue, }; pub use opcode::{Instruction, OpCode, OPCODE_INFO_JUMPTABLE}; pub use primitives::{MAX_CODE_SIZE, MAX_INITCODE_SIZE};