From b976144808950127d8b20ca31dbacf66d3eb8d3f Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Tue, 5 Nov 2024 19:53:00 +0100 Subject: [PATCH] serde: implement `serialize_option` (#89) --- crates/exex/src/serde.rs | 206 +++- crates/exex/testdata/model_option.cairo | 10 + crates/exex/testdata/model_option.json | 1209 +++++++++++++++++++++++ 3 files changed, 1403 insertions(+), 22 deletions(-) create mode 100644 crates/exex/testdata/model_option.cairo create mode 100644 crates/exex/testdata/model_option.json diff --git a/crates/exex/src/serde.rs b/crates/exex/src/serde.rs index 2aba368e..8071d13a 100644 --- a/crates/exex/src/serde.rs +++ b/crates/exex/src/serde.rs @@ -50,6 +50,13 @@ pub enum KakarotSerdeError { /// The name of the missing field. field: String, }, + + /// Error variant indicating that an invalid value was encountered during serialization. + #[error("Invalid value for field '{field}' in serialization process.")] + InvalidFieldValue { + /// The name of the invalid field. + field: String, + }, } /// Represents the types used in Cairo, including felt types, pointers, tuples, and structs. @@ -344,6 +351,37 @@ impl KakarotSerde { } } + /// Serializes an optional value at the specified pointer in Cairo memory. + /// + /// In Cairo, a `model.Option` contains two fields: + /// - `is_some`: A boolean field indicating whether the option contains a value. + /// - `value`: The value contained in the option, if `is_some` is `true`. + /// + /// # Errors + /// + /// This function returns an error if: + /// - The `is_some` field is not `0` or `1`. + /// - The `is_some` field is `1`, but the `value` field is missing. + pub fn serialize_option( + &self, + ptr: Relocatable, + ) -> Result, KakarotSerdeError> { + // Retrieve the serialized "Option" struct as a map of field names to values. + let raw = self.serialize_pointers("model.Option", ptr)?; + + // Validate the "is_some" field. + match raw.get("is_some") { + Some(Some(MaybeRelocatable::Int(v))) if *v == Felt252::ZERO => Ok(None), + Some(Some(MaybeRelocatable::Int(v))) if *v == Felt252::ONE => { + // `is_some` is `1`, so check for "value" field. + raw.get("value") + .cloned() + .ok_or_else(|| KakarotSerdeError::MissingField { field: "value".to_string() }) + } + _ => Err(KakarotSerdeError::InvalidFieldValue { field: "is_some".to_string() }), + } + } + /// Serializes the specified scope within the Cairo VM by attempting to extract /// a specific data structure based on the scope's path. pub fn serialize_scope( @@ -389,9 +427,28 @@ mod tests { }; use std::str::FromStr; - fn setup_kakarot_serde() -> KakarotSerde { + /// Represents different test programs used for testing serialization and deserialization. + enum TestProgram { + KeccakAddUint256, + ModelOption, + } + + impl TestProgram { + /// Retrieves the byte representation of the selected test program. + /// + /// This method returns the contents of the JSON file associated with each test program, + /// allowing the test runner to load the serialized test data directly into memory. + fn path(&self) -> &[u8] { + match self { + Self::KeccakAddUint256 => include_bytes!("../testdata/keccak_add_uint256.json"), + Self::ModelOption => include_bytes!("../testdata/model_option.json"), + } + } + } + + fn setup_kakarot_serde(test_program: TestProgram) -> KakarotSerde { // Load the valid program content from a JSON file - let program_content = include_bytes!("../testdata/keccak_add_uint256.json"); + let program_content = test_program.path(); // Create a Program instance from the loaded bytes, specifying "main" as the entry point let program = Program::from_bytes(program_content, Some("main")).unwrap(); @@ -406,7 +463,7 @@ mod tests { #[test] fn test_program_identifier_valid() { // Setup the KakarotSerde instance - let kakarot_serde = setup_kakarot_serde(); + let kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Check if the identifier "main" with expected type "function" is correctly retrieved assert_eq!( @@ -440,7 +497,7 @@ mod tests { #[test] fn test_non_existent_identifier() { // Setup the KakarotSerde instance - let kakarot_serde = setup_kakarot_serde(); + let kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Test for a non-existent identifier let result = @@ -459,7 +516,7 @@ mod tests { #[test] fn test_incorrect_identifier_usage() { // Setup the KakarotSerde instance - let kakarot_serde = setup_kakarot_serde(); + let kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Test for an identifier used incorrectly (not the last segment of the full name) let result = kakarot_serde.get_identifier("check_range", Some("struct".to_string())); @@ -477,7 +534,7 @@ mod tests { #[test] fn test_valid_identifier_incorrect_type() { // Setup the KakarotSerde instance - let kakarot_serde = setup_kakarot_serde(); + let kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Test for a valid identifier but with an incorrect type let result = kakarot_serde.get_identifier("main", Some("struct".to_string())); @@ -495,7 +552,7 @@ mod tests { #[test] fn test_identifier_with_multiple_matches() { // Setup the KakarotSerde instance - let kakarot_serde = setup_kakarot_serde(); + let kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Test for an identifier with multiple matches let result = kakarot_serde.get_identifier("ImplicitArgs", Some("struct".to_string())); @@ -514,7 +571,7 @@ mod tests { #[test] fn test_serialize_pointer_not_struct() { // Setup the KakarotSerde instance - let mut kakarot_serde = setup_kakarot_serde(); + let mut kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Add a new memory segment to the virtual machine (VM). let base = kakarot_serde.runner.vm.add_memory_segment(); @@ -535,7 +592,7 @@ mod tests { #[test] fn test_serialize_pointer_empty() { // Setup the KakarotSerde instance - let kakarot_serde = setup_kakarot_serde(); + let kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Serialize the pointers of the "ImplicitArgs" struct but without any memory segment. let result = kakarot_serde @@ -549,7 +606,7 @@ mod tests { #[test] fn test_serialize_pointer_valid() { // Setup the KakarotSerde instance - let mut kakarot_serde = setup_kakarot_serde(); + let mut kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Setup let output_ptr = Felt252::ZERO; @@ -591,7 +648,7 @@ mod tests { #[test] fn test_serialize_null_no_pointer() { // Setup the KakarotSerde instance - let mut kakarot_serde = setup_kakarot_serde(); + let mut kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Setup let output_ptr = Relocatable { segment_index: 10, offset: 11 }; @@ -631,7 +688,7 @@ mod tests { #[test] fn test_serialize_uint256_0() { // Setup the KakarotSerde instance - let mut kakarot_serde = setup_kakarot_serde(); + let mut kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // U256 to be serialized let x = U256::ZERO; @@ -661,7 +718,7 @@ mod tests { #[test] fn test_serialize_uint256_valid() { // Setup the KakarotSerde instance - let mut kakarot_serde = setup_kakarot_serde(); + let mut kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // U256 to be serialized let x = @@ -693,7 +750,7 @@ mod tests { #[test] fn test_serialize_uint256_not_int_high() { // Setup the KakarotSerde instance - let mut kakarot_serde = setup_kakarot_serde(); + let mut kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // U256 to be serialized let x = U256::MAX; @@ -728,7 +785,7 @@ mod tests { #[test] fn test_serialize_uint256_not_int_low() { // Setup the KakarotSerde instance - let mut kakarot_serde = setup_kakarot_serde(); + let mut kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // U256 to be serialized let x = U256::MAX; @@ -757,7 +814,7 @@ mod tests { #[test] fn test_get_offset_tuple() { // Setup the KakarotSerde instance - let kakarot_serde = setup_kakarot_serde(); + let kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Create Cairo types for Tuple members. let member1 = TupleItem::new(Some("a".to_string()), CairoType::felt_type(None), None); @@ -778,7 +835,7 @@ mod tests { #[test] fn test_get_offset_struct_invalid_identifier() { // Setup the KakarotSerde instance - let kakarot_serde = setup_kakarot_serde(); + let kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Create a Cairo type for a Struct with an invalid identifier. let cairo_type = CairoType::Struct { @@ -801,7 +858,7 @@ mod tests { #[test] fn test_get_offset_struct_valid_identifier() { // Setup the KakarotSerde instance - let kakarot_serde = setup_kakarot_serde(); + let kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Create a Cairo type for a Struct with a valid identifier (3 members). let cairo_type = CairoType::Struct { @@ -816,7 +873,7 @@ mod tests { #[test] fn test_get_offset_struct_valid_identifier_without_members() { // Setup the KakarotSerde instance - let kakarot_serde = setup_kakarot_serde(); + let kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Create a Cairo type for a Struct with a valid identifier (no members). let cairo_type = CairoType::Struct { @@ -831,7 +888,7 @@ mod tests { #[test] fn test_get_offset_felt_pointer() { // Setup the KakarotSerde instance - let kakarot_serde = setup_kakarot_serde(); + let kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Create a Cairo type for a Felt. let cairo_type = CairoType::felt_type(None); @@ -1000,7 +1057,7 @@ mod tests { #[test] fn test_serialize_inner_felt() { // Setup the KakarotSerde instance - let mut kakarot_serde = setup_kakarot_serde(); + let mut kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Setup let output_ptr = Relocatable { segment_index: 10, offset: 11 }; @@ -1056,7 +1113,7 @@ mod tests { #[test] fn test_serialize_scope_uint256() { // Setup the KakarotSerde instance - let mut kakarot_serde = setup_kakarot_serde(); + let mut kakarot_serde = setup_kakarot_serde(TestProgram::KeccakAddUint256); // Define a ScopedName ending in "Uint256" let scope = ScopedName { @@ -1095,4 +1152,109 @@ mod tests { // Assert that the result matches the expected serialized U256 value assert_eq!(result, Ok(SerializedScope::U256(x))); } + + #[test] + fn test_serialize_option_some_value() { + // Setup KakarotSerde instance + let mut kakarot_serde = setup_kakarot_serde(TestProgram::ModelOption); + + // Setup + let is_some = Felt252::ONE; + let value_ptr = kakarot_serde.runner.vm.add_memory_segment(); + + // Insert values in memory + let base = kakarot_serde + .runner + .vm + .gen_arg(&vec![ + MaybeRelocatable::Int(is_some), + MaybeRelocatable::RelocatableValue(value_ptr), + ]) + .unwrap() + .get_relocatable() + .unwrap(); + + // Serialize the Option struct using the new memory segment. + let result = + kakarot_serde.serialize_option(base).expect("failed to serialize model.Option"); + + // Assert that the result matches the expected serialized struct members. + assert_eq!(result, Some(MaybeRelocatable::RelocatableValue(value_ptr))); + } + + #[test] + fn test_serialize_option_none_value() { + // Setup KakarotSerde instance + let mut kakarot_serde = setup_kakarot_serde(TestProgram::ModelOption); + + // Setup `is_some` as 0 to indicate None + let is_some = Felt252::ZERO; + + // Insert values in memory + let base = kakarot_serde + .runner + .vm + .gen_arg(&vec![MaybeRelocatable::Int(is_some)]) + .unwrap() + .get_relocatable() + .unwrap(); + + // Serialize the Option struct with `is_some` as `false`. + let result = + kakarot_serde.serialize_option(base).expect("failed to serialize model.Option"); + + // Assert that the result is None since `is_some` is `false`. + assert!(result.is_none()); + } + + #[test] + fn test_serialize_option_missing_value_error() { + // Setup KakarotSerde instance + let mut kakarot_serde = setup_kakarot_serde(TestProgram::ModelOption); + + // Set `is_some` to 1 but don't provide a `value` field to trigger an error. + let is_some = Felt252::ONE; + + // Insert `is_some` in memory without a corresponding `value`. + let base = kakarot_serde + .runner + .vm + .gen_arg(&vec![MaybeRelocatable::Int(is_some)]) + .unwrap() + .get_relocatable() + .unwrap(); + + // Serialize the Option struct expecting an error due to missing `value`. + let result = kakarot_serde.serialize_option(base); + + // Assert that an error is returned for the missing `value` field. + assert_eq!(result, Err(KakarotSerdeError::MissingField { field: "value".to_string() })); + } + + #[test] + fn test_serialize_option_invalid_is_some_error() { + // Setup KakarotSerde instance + let mut kakarot_serde = setup_kakarot_serde(TestProgram::ModelOption); + + // Set `is_some` to an invalid value (e.g., 2) to trigger an error. + let invalid_is_some = Felt252::from(2); + + // Insert invalid `is_some` in memory. + let base = kakarot_serde + .runner + .vm + .gen_arg(&vec![MaybeRelocatable::Int(invalid_is_some)]) + .unwrap() + .get_relocatable() + .unwrap(); + + // Serialize the Option struct expecting an error due to invalid `is_some`. + let result = kakarot_serde.serialize_option(base); + + // Assert that an error is returned for the invalid `is_some` value. + assert_eq!( + result, + Err(KakarotSerdeError::InvalidFieldValue { field: "is_some".to_string() }) + ); + } } diff --git a/crates/exex/testdata/model_option.cairo b/crates/exex/testdata/model_option.cairo new file mode 100644 index 00000000..f0529cca --- /dev/null +++ b/crates/exex/testdata/model_option.cairo @@ -0,0 +1,10 @@ +%builtins output range_check + +from src.model import model + +func main{output_ptr: felt*, range_check_ptr}() { + let address = 0xdead; + let res = model.Option(is_some=1, value=address); + + return (); +} diff --git a/crates/exex/testdata/model_option.json b/crates/exex/testdata/model_option.json new file mode 100644 index 00000000..a33628c3 --- /dev/null +++ b/crates/exex/testdata/model_option.json @@ -0,0 +1,1209 @@ +{ + "attributes": [], + "builtins": ["output", "range_check"], + "compiler_version": "0.13.2", + "data": [ + "0x40780017fff7fff", + "0x2", + "0x1104800180018000", + "0x4", + "0x10780017fff7fff", + "0x0", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x208b7fff7fff7ffe" + ], + "debug_info": null, + "hints": {}, + "identifiers": { + "__main__.__end__": { + "pc": 4, + "type": "label" + }, + "__main__.__start__": { + "pc": 0, + "type": "label" + }, + "__main__.main": { + "decorators": [], + "pc": 6, + "type": "function" + }, + "__main__.main.Args": { + "full_name": "__main__.main.Args", + "members": {}, + "size": 0, + "type": "struct" + }, + "__main__.main.ImplicitArgs": { + "full_name": "__main__.main.ImplicitArgs", + "members": { + "output_ptr": { + "cairo_type": "felt*", + "offset": 0 + }, + "range_check_ptr": { + "cairo_type": "felt", + "offset": 1 + } + }, + "size": 2, + "type": "struct" + }, + "__main__.main.Return": { + "cairo_type": "()", + "type": "type_definition" + }, + "__main__.main.SIZEOF_LOCALS": { + "type": "const", + "value": 0 + }, + "__main__.main.address": { + "cairo_type": "felt", + "full_name": "__main__.main.address", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "cast(57005, felt)" + } + ], + "type": "reference" + }, + "__main__.main.output_ptr": { + "cairo_type": "felt*", + "full_name": "__main__.main.output_ptr", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-4), felt**)]" + } + ], + "type": "reference" + }, + "__main__.main.range_check_ptr": { + "cairo_type": "felt", + "full_name": "__main__.main.range_check_ptr", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-3), felt*)]" + } + ], + "type": "reference" + }, + "__main__.main.res": { + "cairo_type": "src.model.model.Option", + "full_name": "__main__.main.res", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "cast((1, 57005), src.model.model.Option)" + } + ], + "type": "reference" + }, + "__main__.model": { + "destination": "src.model.model", + "type": "alias" + }, + "src.model.DictAccess": { + "destination": "starkware.cairo.common.dict.DictAccess", + "type": "alias" + }, + "src.model.Uint256": { + "destination": "starkware.cairo.common.uint256.Uint256", + "type": "alias" + }, + "src.model.model": { + "type": "namespace" + }, + "src.model.model.Account": { + "full_name": "src.model.model.Account", + "members": { + "balance": { + "cairo_type": "starkware.cairo.common.uint256.Uint256*", + "offset": 10 + }, + "code": { + "cairo_type": "felt*", + "offset": 1 + }, + "code_hash": { + "cairo_type": "starkware.cairo.common.uint256.Uint256*", + "offset": 2 + }, + "code_len": { + "cairo_type": "felt", + "offset": 0 + }, + "created": { + "cairo_type": "felt", + "offset": 12 + }, + "nonce": { + "cairo_type": "felt", + "offset": 9 + }, + "selfdestruct": { + "cairo_type": "felt", + "offset": 11 + }, + "storage": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 4 + }, + "storage_start": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 3 + }, + "transient_storage": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 6 + }, + "transient_storage_start": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 5 + }, + "valid_jumpdests": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 8 + }, + "valid_jumpdests_start": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 7 + } + }, + "size": 13, + "type": "struct" + }, + "src.model.model.Args": { + "full_name": "src.model.model.Args", + "members": {}, + "size": 0, + "type": "struct" + }, + "src.model.model.Block": { + "full_name": "src.model.model.Block", + "members": { + "block_header": { + "cairo_type": "src.model.model.BlockHeader*", + "offset": 0 + }, + "transactions": { + "cairo_type": "src.model.model.TransactionEncoded*", + "offset": 2 + }, + "transactions_len": { + "cairo_type": "felt", + "offset": 1 + } + }, + "size": 3, + "type": "struct" + }, + "src.model.model.BlockHeader": { + "full_name": "src.model.model.BlockHeader", + "members": { + "base_fee_per_gas": { + "cairo_type": "src.model.model.Option", + "offset": 23 + }, + "blob_gas_used": { + "cairo_type": "src.model.model.Option", + "offset": 25 + }, + "bloom": { + "cairo_type": "felt*", + "offset": 13 + }, + "coinbase": { + "cairo_type": "felt", + "offset": 4 + }, + "difficulty": { + "cairo_type": "starkware.cairo.common.uint256.Uint256", + "offset": 14 + }, + "excess_blob_gas": { + "cairo_type": "src.model.model.Option", + "offset": 27 + }, + "extra_data": { + "cairo_type": "felt*", + "offset": 34 + }, + "extra_data_len": { + "cairo_type": "felt", + "offset": 33 + }, + "gas_limit": { + "cairo_type": "felt", + "offset": 17 + }, + "gas_used": { + "cairo_type": "felt", + "offset": 18 + }, + "mix_hash": { + "cairo_type": "starkware.cairo.common.uint256.Uint256", + "offset": 20 + }, + "nonce": { + "cairo_type": "felt", + "offset": 22 + }, + "number": { + "cairo_type": "felt", + "offset": 16 + }, + "ommers_hash": { + "cairo_type": "starkware.cairo.common.uint256.Uint256", + "offset": 2 + }, + "parent_beacon_block_root": { + "cairo_type": "src.model.model.Option", + "offset": 29 + }, + "parent_hash": { + "cairo_type": "starkware.cairo.common.uint256.Uint256", + "offset": 0 + }, + "receipt_root": { + "cairo_type": "starkware.cairo.common.uint256.Uint256", + "offset": 9 + }, + "requests_root": { + "cairo_type": "src.model.model.Option", + "offset": 31 + }, + "state_root": { + "cairo_type": "starkware.cairo.common.uint256.Uint256", + "offset": 5 + }, + "timestamp": { + "cairo_type": "felt", + "offset": 19 + }, + "transactions_root": { + "cairo_type": "starkware.cairo.common.uint256.Uint256", + "offset": 7 + }, + "withdrawals_root": { + "cairo_type": "src.model.model.Option", + "offset": 11 + } + }, + "size": 35, + "type": "struct" + }, + "src.model.model.EVM": { + "full_name": "src.model.model.EVM", + "members": { + "gas_left": { + "cairo_type": "felt", + "offset": 5 + }, + "gas_refund": { + "cairo_type": "felt", + "offset": 6 + }, + "message": { + "cairo_type": "src.model.model.Message*", + "offset": 0 + }, + "program_counter": { + "cairo_type": "felt", + "offset": 3 + }, + "return_data": { + "cairo_type": "felt*", + "offset": 2 + }, + "return_data_len": { + "cairo_type": "felt", + "offset": 1 + }, + "reverted": { + "cairo_type": "felt", + "offset": 7 + }, + "stopped": { + "cairo_type": "felt", + "offset": 4 + } + }, + "size": 8, + "type": "struct" + }, + "src.model.model.Environment": { + "full_name": "src.model.model.Environment", + "members": { + "base_fee": { + "cairo_type": "felt", + "offset": 9 + }, + "block_gas_limit": { + "cairo_type": "felt", + "offset": 6 + }, + "block_number": { + "cairo_type": "felt", + "offset": 5 + }, + "block_timestamp": { + "cairo_type": "felt", + "offset": 7 + }, + "chain_id": { + "cairo_type": "felt", + "offset": 2 + }, + "coinbase": { + "cairo_type": "felt", + "offset": 8 + }, + "gas_price": { + "cairo_type": "felt", + "offset": 1 + }, + "origin": { + "cairo_type": "felt", + "offset": 0 + }, + "prev_randao": { + "cairo_type": "starkware.cairo.common.uint256.Uint256", + "offset": 3 + } + }, + "size": 10, + "type": "struct" + }, + "src.model.model.Event": { + "full_name": "src.model.model.Event", + "members": { + "data": { + "cairo_type": "felt*", + "offset": 3 + }, + "data_len": { + "cairo_type": "felt", + "offset": 2 + }, + "topics": { + "cairo_type": "felt*", + "offset": 1 + }, + "topics_len": { + "cairo_type": "felt", + "offset": 0 + } + }, + "size": 4, + "type": "struct" + }, + "src.model.model.ImplicitArgs": { + "full_name": "src.model.model.ImplicitArgs", + "members": {}, + "size": 0, + "type": "struct" + }, + "src.model.model.Memory": { + "full_name": "src.model.model.Memory", + "members": { + "word_dict": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 1 + }, + "word_dict_start": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 0 + }, + "words_len": { + "cairo_type": "felt", + "offset": 2 + } + }, + "size": 3, + "type": "struct" + }, + "src.model.model.MemoryExpansion": { + "full_name": "src.model.model.MemoryExpansion", + "members": { + "cost": { + "cairo_type": "felt", + "offset": 0 + }, + "new_words_len": { + "cairo_type": "felt", + "offset": 1 + } + }, + "size": 2, + "type": "struct" + }, + "src.model.model.Message": { + "full_name": "src.model.model.Message", + "members": { + "address": { + "cairo_type": "felt", + "offset": 9 + }, + "bytecode": { + "cairo_type": "felt*", + "offset": 0 + }, + "bytecode_len": { + "cairo_type": "felt", + "offset": 1 + }, + "cairo_precompile_called": { + "cairo_type": "felt", + "offset": 15 + }, + "calldata": { + "cairo_type": "felt*", + "offset": 4 + }, + "calldata_len": { + "cairo_type": "felt", + "offset": 5 + }, + "caller": { + "cairo_type": "felt", + "offset": 7 + }, + "code_address": { + "cairo_type": "felt", + "offset": 10 + }, + "depth": { + "cairo_type": "felt", + "offset": 13 + }, + "env": { + "cairo_type": "src.model.model.Environment*", + "offset": 14 + }, + "is_create": { + "cairo_type": "felt", + "offset": 12 + }, + "parent": { + "cairo_type": "src.model.model.Parent*", + "offset": 8 + }, + "read_only": { + "cairo_type": "felt", + "offset": 11 + }, + "valid_jumpdests": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 3 + }, + "valid_jumpdests_start": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 2 + }, + "value": { + "cairo_type": "starkware.cairo.common.uint256.Uint256*", + "offset": 6 + } + }, + "size": 16, + "type": "struct" + }, + "src.model.model.Opcode": { + "full_name": "src.model.model.Opcode", + "members": { + "gas": { + "cairo_type": "felt", + "offset": 1 + }, + "number": { + "cairo_type": "felt", + "offset": 0 + }, + "stack_input": { + "cairo_type": "felt", + "offset": 2 + }, + "stack_size_diff": { + "cairo_type": "felt", + "offset": 4 + }, + "stack_size_min": { + "cairo_type": "felt", + "offset": 3 + } + }, + "size": 5, + "type": "struct" + }, + "src.model.model.Option": { + "full_name": "src.model.model.Option", + "members": { + "is_some": { + "cairo_type": "felt", + "offset": 0 + }, + "value": { + "cairo_type": "felt", + "offset": 1 + } + }, + "size": 2, + "type": "struct" + }, + "src.model.model.Parent": { + "full_name": "src.model.model.Parent", + "members": { + "evm": { + "cairo_type": "src.model.model.EVM*", + "offset": 0 + }, + "memory": { + "cairo_type": "src.model.model.Memory*", + "offset": 2 + }, + "stack": { + "cairo_type": "src.model.model.Stack*", + "offset": 1 + }, + "state": { + "cairo_type": "src.model.model.State*", + "offset": 3 + } + }, + "size": 4, + "type": "struct" + }, + "src.model.model.Return": { + "cairo_type": "()", + "type": "type_definition" + }, + "src.model.model.SIZEOF_LOCALS": { + "type": "const", + "value": 0 + }, + "src.model.model.Stack": { + "full_name": "src.model.model.Stack", + "members": { + "dict_ptr": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 1 + }, + "dict_ptr_start": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 0 + }, + "size": { + "cairo_type": "felt", + "offset": 2 + } + }, + "size": 3, + "type": "struct" + }, + "src.model.model.State": { + "full_name": "src.model.model.State", + "members": { + "accounts": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 1 + }, + "accounts_start": { + "cairo_type": "starkware.cairo.common.dict_access.DictAccess*", + "offset": 0 + }, + "events": { + "cairo_type": "src.model.model.Event*", + "offset": 3 + }, + "events_len": { + "cairo_type": "felt", + "offset": 2 + }, + "transfers": { + "cairo_type": "src.model.model.Transfer*", + "offset": 5 + }, + "transfers_len": { + "cairo_type": "felt", + "offset": 4 + } + }, + "size": 6, + "type": "struct" + }, + "src.model.model.Transaction": { + "full_name": "src.model.model.Transaction", + "members": { + "access_list": { + "cairo_type": "felt*", + "offset": 11 + }, + "access_list_len": { + "cairo_type": "felt", + "offset": 10 + }, + "amount": { + "cairo_type": "starkware.cairo.common.uint256.Uint256", + "offset": 6 + }, + "chain_id": { + "cairo_type": "src.model.model.Option", + "offset": 12 + }, + "destination": { + "cairo_type": "src.model.model.Option", + "offset": 4 + }, + "gas_limit": { + "cairo_type": "felt", + "offset": 1 + }, + "max_fee_per_gas": { + "cairo_type": "felt", + "offset": 3 + }, + "max_priority_fee_per_gas": { + "cairo_type": "felt", + "offset": 2 + }, + "payload": { + "cairo_type": "felt*", + "offset": 9 + }, + "payload_len": { + "cairo_type": "felt", + "offset": 8 + }, + "signer_nonce": { + "cairo_type": "felt", + "offset": 0 + } + }, + "size": 14, + "type": "struct" + }, + "src.model.model.TransactionEncoded": { + "full_name": "src.model.model.TransactionEncoded", + "members": { + "rlp": { + "cairo_type": "felt*", + "offset": 1 + }, + "rlp_len": { + "cairo_type": "felt", + "offset": 0 + }, + "sender": { + "cairo_type": "felt", + "offset": 4 + }, + "signature": { + "cairo_type": "felt*", + "offset": 3 + }, + "signature_len": { + "cairo_type": "felt", + "offset": 2 + } + }, + "size": 5, + "type": "struct" + }, + "src.model.model.Transfer": { + "full_name": "src.model.model.Transfer", + "members": { + "amount": { + "cairo_type": "starkware.cairo.common.uint256.Uint256", + "offset": 2 + }, + "recipient": { + "cairo_type": "felt", + "offset": 1 + }, + "sender": { + "cairo_type": "felt", + "offset": 0 + } + }, + "size": 4, + "type": "struct" + }, + "starkware.cairo.common.bitwise.ALL_ONES": { + "type": "const", + "value": -106710729501573572985208420194530329073740042555888586719234 + }, + "starkware.cairo.common.bitwise.BitwiseBuiltin": { + "destination": "starkware.cairo.common.cairo_builtins.BitwiseBuiltin", + "type": "alias" + }, + "starkware.cairo.common.bool.FALSE": { + "type": "const", + "value": 0 + }, + "starkware.cairo.common.bool.TRUE": { + "type": "const", + "value": 1 + }, + "starkware.cairo.common.cairo_builtins.BitwiseBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.BitwiseBuiltin", + "members": { + "x": { + "cairo_type": "felt", + "offset": 0 + }, + "x_and_y": { + "cairo_type": "felt", + "offset": 2 + }, + "x_or_y": { + "cairo_type": "felt", + "offset": 4 + }, + "x_xor_y": { + "cairo_type": "felt", + "offset": 3 + }, + "y": { + "cairo_type": "felt", + "offset": 1 + } + }, + "size": 5, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.EcOpBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.EcOpBuiltin", + "members": { + "m": { + "cairo_type": "felt", + "offset": 4 + }, + "p": { + "cairo_type": "starkware.cairo.common.ec_point.EcPoint", + "offset": 0 + }, + "q": { + "cairo_type": "starkware.cairo.common.ec_point.EcPoint", + "offset": 2 + }, + "r": { + "cairo_type": "starkware.cairo.common.ec_point.EcPoint", + "offset": 5 + } + }, + "size": 7, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.EcPoint": { + "destination": "starkware.cairo.common.ec_point.EcPoint", + "type": "alias" + }, + "starkware.cairo.common.cairo_builtins.HashBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.HashBuiltin", + "members": { + "result": { + "cairo_type": "felt", + "offset": 2 + }, + "x": { + "cairo_type": "felt", + "offset": 0 + }, + "y": { + "cairo_type": "felt", + "offset": 1 + } + }, + "size": 3, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.KeccakBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.KeccakBuiltin", + "members": { + "input": { + "cairo_type": "starkware.cairo.common.keccak_state.KeccakBuiltinState", + "offset": 0 + }, + "output": { + "cairo_type": "starkware.cairo.common.keccak_state.KeccakBuiltinState", + "offset": 8 + } + }, + "size": 16, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.KeccakBuiltinState": { + "destination": "starkware.cairo.common.keccak_state.KeccakBuiltinState", + "type": "alias" + }, + "starkware.cairo.common.cairo_builtins.ModBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.ModBuiltin", + "members": { + "n": { + "cairo_type": "felt", + "offset": 6 + }, + "offsets_ptr": { + "cairo_type": "felt*", + "offset": 5 + }, + "p": { + "cairo_type": "starkware.cairo.common.cairo_builtins.UInt384", + "offset": 0 + }, + "values_ptr": { + "cairo_type": "starkware.cairo.common.cairo_builtins.UInt384*", + "offset": 4 + } + }, + "size": 7, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.PoseidonBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.PoseidonBuiltin", + "members": { + "input": { + "cairo_type": "starkware.cairo.common.poseidon_state.PoseidonBuiltinState", + "offset": 0 + }, + "output": { + "cairo_type": "starkware.cairo.common.poseidon_state.PoseidonBuiltinState", + "offset": 3 + } + }, + "size": 6, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.PoseidonBuiltinState": { + "destination": "starkware.cairo.common.poseidon_state.PoseidonBuiltinState", + "type": "alias" + }, + "starkware.cairo.common.cairo_builtins.SignatureBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.SignatureBuiltin", + "members": { + "message": { + "cairo_type": "felt", + "offset": 1 + }, + "pub_key": { + "cairo_type": "felt", + "offset": 0 + } + }, + "size": 2, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.UInt384": { + "full_name": "starkware.cairo.common.cairo_builtins.UInt384", + "members": { + "d0": { + "cairo_type": "felt", + "offset": 0 + }, + "d1": { + "cairo_type": "felt", + "offset": 1 + }, + "d2": { + "cairo_type": "felt", + "offset": 2 + }, + "d3": { + "cairo_type": "felt", + "offset": 3 + } + }, + "size": 4, + "type": "struct" + }, + "starkware.cairo.common.dict.DictAccess": { + "destination": "starkware.cairo.common.dict_access.DictAccess", + "type": "alias" + }, + "starkware.cairo.common.dict.squash_dict": { + "destination": "starkware.cairo.common.squash_dict.squash_dict", + "type": "alias" + }, + "starkware.cairo.common.dict_access.DictAccess": { + "full_name": "starkware.cairo.common.dict_access.DictAccess", + "members": { + "key": { + "cairo_type": "felt", + "offset": 0 + }, + "new_value": { + "cairo_type": "felt", + "offset": 2 + }, + "prev_value": { + "cairo_type": "felt", + "offset": 1 + } + }, + "size": 3, + "type": "struct" + }, + "starkware.cairo.common.ec_point.EcPoint": { + "full_name": "starkware.cairo.common.ec_point.EcPoint", + "members": { + "x": { + "cairo_type": "felt", + "offset": 0 + }, + "y": { + "cairo_type": "felt", + "offset": 1 + } + }, + "size": 2, + "type": "struct" + }, + "starkware.cairo.common.keccak_state.KeccakBuiltinState": { + "full_name": "starkware.cairo.common.keccak_state.KeccakBuiltinState", + "members": { + "s0": { + "cairo_type": "felt", + "offset": 0 + }, + "s1": { + "cairo_type": "felt", + "offset": 1 + }, + "s2": { + "cairo_type": "felt", + "offset": 2 + }, + "s3": { + "cairo_type": "felt", + "offset": 3 + }, + "s4": { + "cairo_type": "felt", + "offset": 4 + }, + "s5": { + "cairo_type": "felt", + "offset": 5 + }, + "s6": { + "cairo_type": "felt", + "offset": 6 + }, + "s7": { + "cairo_type": "felt", + "offset": 7 + } + }, + "size": 8, + "type": "struct" + }, + "starkware.cairo.common.math.FALSE": { + "destination": "starkware.cairo.common.bool.FALSE", + "type": "alias" + }, + "starkware.cairo.common.math.TRUE": { + "destination": "starkware.cairo.common.bool.TRUE", + "type": "alias" + }, + "starkware.cairo.common.math_cmp.RC_BOUND": { + "type": "const", + "value": 340282366920938463463374607431768211456 + }, + "starkware.cairo.common.math_cmp.assert_le_felt": { + "destination": "starkware.cairo.common.math.assert_le_felt", + "type": "alias" + }, + "starkware.cairo.common.math_cmp.assert_lt_felt": { + "destination": "starkware.cairo.common.math.assert_lt_felt", + "type": "alias" + }, + "starkware.cairo.common.poseidon_state.PoseidonBuiltinState": { + "full_name": "starkware.cairo.common.poseidon_state.PoseidonBuiltinState", + "members": { + "s0": { + "cairo_type": "felt", + "offset": 0 + }, + "s1": { + "cairo_type": "felt", + "offset": 1 + }, + "s2": { + "cairo_type": "felt", + "offset": 2 + } + }, + "size": 3, + "type": "struct" + }, + "starkware.cairo.common.pow.assert_le": { + "destination": "starkware.cairo.common.math.assert_le", + "type": "alias" + }, + "starkware.cairo.common.pow.get_ap": { + "destination": "starkware.cairo.common.registers.get_ap", + "type": "alias" + }, + "starkware.cairo.common.pow.get_fp_and_pc": { + "destination": "starkware.cairo.common.registers.get_fp_and_pc", + "type": "alias" + }, + "starkware.cairo.common.pow.sign": { + "destination": "starkware.cairo.common.math.sign", + "type": "alias" + }, + "starkware.cairo.common.registers.get_ap": { + "destination": "starkware.cairo.lang.compiler.lib.registers.get_ap", + "type": "alias" + }, + "starkware.cairo.common.registers.get_fp_and_pc": { + "destination": "starkware.cairo.lang.compiler.lib.registers.get_fp_and_pc", + "type": "alias" + }, + "starkware.cairo.common.squash_dict.DictAccess": { + "destination": "starkware.cairo.common.dict_access.DictAccess", + "type": "alias" + }, + "starkware.cairo.common.squash_dict.assert_lt_felt": { + "destination": "starkware.cairo.common.math.assert_lt_felt", + "type": "alias" + }, + "starkware.cairo.common.uint256.ALL_ONES": { + "type": "const", + "value": 340282366920938463463374607431768211455 + }, + "starkware.cairo.common.uint256.BitwiseBuiltin": { + "destination": "starkware.cairo.common.cairo_builtins.BitwiseBuiltin", + "type": "alias" + }, + "starkware.cairo.common.uint256.HALF_SHIFT": { + "type": "const", + "value": 18446744073709551616 + }, + "starkware.cairo.common.uint256.SHIFT": { + "type": "const", + "value": 340282366920938463463374607431768211456 + }, + "starkware.cairo.common.uint256.Uint256": { + "full_name": "starkware.cairo.common.uint256.Uint256", + "members": { + "high": { + "cairo_type": "felt", + "offset": 1 + }, + "low": { + "cairo_type": "felt", + "offset": 0 + } + }, + "size": 2, + "type": "struct" + }, + "starkware.cairo.common.uint256.assert_in_range": { + "destination": "starkware.cairo.common.math.assert_in_range", + "type": "alias" + }, + "starkware.cairo.common.uint256.assert_le": { + "destination": "starkware.cairo.common.math.assert_le", + "type": "alias" + }, + "starkware.cairo.common.uint256.assert_nn_le": { + "destination": "starkware.cairo.common.math.assert_nn_le", + "type": "alias" + }, + "starkware.cairo.common.uint256.assert_not_zero": { + "destination": "starkware.cairo.common.math.assert_not_zero", + "type": "alias" + }, + "starkware.cairo.common.uint256.bitwise_and": { + "destination": "starkware.cairo.common.bitwise.bitwise_and", + "type": "alias" + }, + "starkware.cairo.common.uint256.bitwise_or": { + "destination": "starkware.cairo.common.bitwise.bitwise_or", + "type": "alias" + }, + "starkware.cairo.common.uint256.bitwise_xor": { + "destination": "starkware.cairo.common.bitwise.bitwise_xor", + "type": "alias" + }, + "starkware.cairo.common.uint256.get_ap": { + "destination": "starkware.cairo.common.registers.get_ap", + "type": "alias" + }, + "starkware.cairo.common.uint256.get_fp_and_pc": { + "destination": "starkware.cairo.common.registers.get_fp_and_pc", + "type": "alias" + }, + "starkware.cairo.common.uint256.is_le": { + "destination": "starkware.cairo.common.math_cmp.is_le", + "type": "alias" + }, + "starkware.cairo.common.uint256.pow": { + "destination": "starkware.cairo.common.pow.pow", + "type": "alias" + }, + "starkware.cairo.common.uint256.split_felt": { + "destination": "starkware.cairo.common.math.split_felt", + "type": "alias" + } + }, + "main_scope": "__main__", + "prime": "0x800000000000011000000000000000000000000000000000000000000000001", + "reference_manager": { + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-4), felt**)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-3), felt*)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "cast(57005, felt)" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "cast((1, 57005), src.model.model.Option)" + } + ] + } +}