diff --git a/Cargo.lock b/Cargo.lock index 51fd33383..d104810f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -985,6 +985,7 @@ dependencies = [ "thiserror", "tracing", "tracing-subscriber", + "utf8_iter", "walkdir", ] @@ -996,7 +997,6 @@ dependencies = [ "lazy_static", "libc", "rand", - "starknet-crypto 0.7.1", "starknet-curve 0.5.0", "starknet-types-core", ] @@ -1031,7 +1031,7 @@ dependencies = [ "serde_json", "sha2", "sha3", - "starknet-crypto 0.6.2", + "starknet-crypto", "starknet-types-core", "thiserror-no-std", "zip", @@ -3495,32 +3495,12 @@ dependencies = [ "num-traits 0.2.19", "rfc6979", "sha2", - "starknet-crypto-codegen 0.3.3", + "starknet-crypto-codegen", "starknet-curve 0.4.2", "starknet-ff", "zeroize", ] -[[package]] -name = "starknet-crypto" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2a821ad8d98c6c3e4d0e5097f3fe6e2ed120ada9d32be87cd1330c7923a2f0" -dependencies = [ - "crypto-bigint", - "hex", - "hmac", - "num-bigint", - "num-integer", - "num-traits 0.2.19", - "rfc6979", - "sha2", - "starknet-crypto-codegen 0.4.0", - "starknet-curve 0.5.0", - "starknet-types-core", - "zeroize", -] - [[package]] name = "starknet-crypto-codegen" version = "0.3.3" @@ -3532,17 +3512,6 @@ dependencies = [ "syn 2.0.77", ] -[[package]] -name = "starknet-crypto-codegen" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e179dedc3fa6da064e56811d3e05d446aa2f7459e4eb0e3e49378a337235437" -dependencies = [ - "starknet-curve 0.5.0", - "starknet-types-core", - "syn 2.0.77", -] - [[package]] name = "starknet-curve" version = "0.4.2" @@ -4015,6 +3984,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index bf11fc6f8..4e54df248 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,6 +82,7 @@ starknet-types-core = { version = "0.1.5", default-features = false, features = tempfile = "3.6" thiserror = "1.0.59" tracing = "0.1" +utf8_iter = "1.0.4" # CLI dependencies @@ -107,7 +108,7 @@ colored = { version = "2.1.0", optional = true } keccak = "0.1.5" k256 = "0.13.3" p256 = "0.13.2" -sha2 = "0.10.8" # needed for the syscall handler stub +sha2 = "0.10.8" # needed for the syscall handler stub scarb-metadata = { git = "https://github.com/software-mansion/scarb.git", rev = "v2.8.2", optional = true } scarb-ui = { git = "https://github.com/software-mansion/scarb.git", rev = "v2.8.2", optional = true } sec1 = "0.7.3" diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index f9b72d110..835935adc 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -10,11 +10,10 @@ crate-type = ["rlib", "cdylib", "staticlib"] [dependencies] starknet-types-core = { version = "0.1.5", default-features = false, features = [ - "std", "serde", + "std", "serde", "hash" ] } cairo-lang-sierra-gas = "2.8.2" libc = "0.2.158" -starknet-crypto = "0.7.1" starknet-curve = "0.5.0" lazy_static = "1.5.0" rand = "0.8.5" diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 8a95611e6..eb9540118 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -9,6 +9,7 @@ use starknet_curve::curve_params::BETA; use starknet_types_core::{ curve::{AffinePoint, ProjectivePoint}, felt::Felt, + hash::StarkHash, }; use std::ops::Mul; use std::{collections::HashMap, fs::File, io::Write, os::fd::FromRawFd, ptr::NonNull, slice}; @@ -110,7 +111,7 @@ pub unsafe extern "C" fn cairo_native__libfunc__pedersen( let rhs = Felt::from_bytes_le_slice(rhs); // Compute pedersen hash and copy the result into `dst`. - let res = starknet_crypto::pedersen_hash(&lhs, &rhs); + let res = starknet_types_core::hash::Pedersen::hash(&lhs, &rhs); dst.copy_from_slice(&res.to_bytes_le()); } @@ -145,7 +146,7 @@ pub unsafe extern "C" fn cairo_native__libfunc__hades_permutation( ]; // Compute Poseidon permutation. - starknet_crypto::poseidon_permute_comp(&mut state); + starknet_types_core::hash::Poseidon::hades_permutation(&mut state); // Write back the results. op0.copy_from_slice(&state[0].to_bytes_le()); diff --git a/src/execution_result.rs b/src/execution_result.rs index 99d2cb9b8..eeab9427d 100644 --- a/src/execution_result.rs +++ b/src/execution_result.rs @@ -2,7 +2,7 @@ /// /// This module contains the structures used to interpret the program execution results, either /// normal programs or starknet contracts. -use crate::{error::Error, values::JitValue}; +use crate::{error::Error, utils::decode_error_message, values::JitValue}; use starknet_types_core::felt::Felt; #[derive( @@ -126,7 +126,7 @@ impl ContractExecutionResult { // remove null chars .filter(|b| *b != 0) .collect(); - let str_error = String::from_utf8(bytes_err).unwrap().to_owned(); + let str_error = decode_error_message(&bytes_err); error_msg = Some(str_error); felt_vec diff --git a/src/executor/contract.rs b/src/executor/contract.rs index e65c9ce23..354d4a1c2 100644 --- a/src/executor/contract.rs +++ b/src/executor/contract.rs @@ -64,7 +64,7 @@ use crate::{ module::NativeModule, starknet::{handler::StarknetSyscallHandlerCallbacks, StarknetSyscallHandler}, types::TypeBuilder, - utils::{generate_function_name, get_integer_layout}, + utils::{decode_error_message, generate_function_name, get_integer_layout}, OptLevel, }; @@ -401,7 +401,7 @@ impl ContractExecutor { // remove null chars .filter(|b| *b != 0) .collect(); - let str_error = String::from_utf8(bytes_err).unwrap().to_owned(); + let str_error = decode_error_message(&bytes_err); error_msg = Some(str_error); } diff --git a/src/utils.rs b/src/utils.rs index 2f348523d..beeb45329 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -59,6 +59,26 @@ pub fn generate_function_name( } } +/// Decode an UTF-8 error message replacing invalid bytes with their hexadecimal representation, as +/// done by Python's `x.decode('utf-8', errors='backslashreplace')`. +pub fn decode_error_message(data: &[u8]) -> String { + let mut pos = 0; + utf8_iter::ErrorReportingUtf8Chars::new(data).fold(String::new(), |mut acc, ch| { + match ch { + Ok(ch) => { + acc.push(ch); + pos += ch.len_utf8(); + } + Err(_) => { + acc.push_str(&format!("\\x{:02x}", data[pos])); + pos += 1; + } + }; + + acc + }) +} + /// Return the layout for an integer of arbitrary width. /// /// This assumes the platform's maximum (effective) alignment is 16 bytes, and that every integer @@ -866,6 +886,45 @@ pub mod test { assert_eq!(entry_point.unwrap().id.id, 15); } + #[test] + fn decode_error_message() { + // Checkout [issue 795](https://github.com/lambdaclass/cairo_native/issues/795) for context. + assert_eq!( + super::decode_error_message(&[ + 97, 114, 103, 101, 110, 116, 47, 109, 117, 108, 116, 105, 99, 97, 108, 108, 45, + 102, 97, 105, 108, 101, 100, 3, 232, 78, 97, 116, 105, 118, 101, 32, 101, 120, 101, + 99, 117, 116, 105, 111, 110, 32, 101, 114, 114, 111, 114, 58, 32, 69, 114, 114, + 111, 114, 32, 97, 116, 32, 112, 99, 61, 48, 58, 49, 48, 52, 58, 10, 71, 111, 116, + 32, 97, 110, 32, 101, 120, 99, 101, 112, 116, 105, 111, 110, 32, 119, 104, 105, + 108, 101, 32, 101, 120, 101, 99, 117, 116, 105, 110, 103, 32, 97, 32, 104, 105, + 110, 116, 58, 32, 69, 114, 114, 111, 114, 32, 97, 116, 32, 112, 99, 61, 48, 58, 49, + 56, 52, 58, 10, 71, 111, 116, 32, 97, 110, 32, 101, 120, 99, 101, 112, 116, 105, + 111, 110, 32, 119, 104, 105, 108, 101, 32, 101, 120, 101, 99, 117, 116, 105, 110, + 103, 32, 97, 32, 104, 105, 110, 116, 58, 32, 69, 120, 99, 101, 101, 100, 101, 100, + 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, 32, 110, 117, 109, 98, + 101, 114, 32, 111, 102, 32, 101, 118, 101, 110, 116, 115, 44, 32, 110, 117, 109, + 98, 101, 114, 32, 101, 118, 101, 110, 116, 115, 58, 32, 49, 48, 48, 49, 44, 32, + 109, 97, 120, 32, 110, 117, 109, 98, 101, 114, 32, 101, 118, 101, 110, 116, 115, + 58, 32, 49, 48, 48, 48, 46, 10, 67, 97, 105, 114, 111, 32, 116, 114, 97, 99, 101, + 98, 97, 99, 107, 32, 40, 109, 111, 115, 116, 32, 114, 101, 99, 101, 110, 116, 32, + 99, 97, 108, 108, 32, 108, 97, 115, 116, 41, 58, 10, 85, 110, 107, 110, 111, 119, + 110, 32, 108, 111, 99, 97, 116, 105, 111, 110, 32, 40, 112, 99, 61, 48, 58, 49, 52, + 51, 52, 41, 10, 85, 110, 107, 110, 111, 119, 110, 32, 108, 111, 99, 97, 116, 105, + 111, 110, 32, 40, 112, 99, 61, 48, 58, 49, 51, 57, 53, 41, 10, 85, 110, 107, 110, + 111, 119, 110, 32, 108, 111, 99, 97, 116, 105, 111, 110, 32, 40, 112, 99, 61, 48, + 58, 57, 53, 51, 41, 10, 85, 110, 107, 110, 111, 119, 110, 32, 108, 111, 99, 97, + 116, 105, 111, 110, 32, 40, 112, 99, 61, 48, 58, 51, 51, 57, 41, 10, 10, 67, 97, + 105, 114, 111, 32, 116, 114, 97, 99, 101, 98, 97, 99, 107, 32, 40, 109, 111, 115, + 116, 32, 114, 101, 99, 101, 110, 116, 32, 99, 97, 108, 108, 32, 108, 97, 115, 116, + 41, 58, 10, 85, 110, 107, 110, 111, 119, 110, 32, 108, 111, 99, 97, 116, 105, 111, + 110, 32, 40, 112, 99, 61, 48, 58, 49, 54, 55, 56, 41, 10, 85, 110, 107, 110, 111, + 119, 110, 32, 108, 111, 99, 97, 116, 105, 111, 110, 32, 40, 112, 99, 61, 48, 58, + 49, 54, 54, 52, 41, 10 + ]), + "argent/multicall-failed\x03\\xe8Native execution error: Error at pc=0:104:\nGot an exception while executing a hint: Error at pc=0:184:\nGot an exception while executing a hint: Exceeded the maximum number of events, number events: 1001, max number events: 1000.\nCairo traceback (most recent call last):\nUnknown location (pc=0:1434)\nUnknown location (pc=0:1395)\nUnknown location (pc=0:953)\nUnknown location (pc=0:339)\n\nCairo traceback (most recent call last):\nUnknown location (pc=0:1678)\nUnknown location (pc=0:1664)\n", + ); + } + // ============================== // == TESTS: felt252_str // ==============================