From 15948e9f32950ce8282d8138dc7e74f20ae787b1 Mon Sep 17 00:00:00 2001 From: Pedro Fontana Date: Mon, 29 May 2023 18:09:01 -0300 Subject: [PATCH 1/4] Handle scientific notation cases in fn felt_from_number --- src/serde/deserialize_program.rs | 38 ++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/serde/deserialize_program.rs b/src/serde/deserialize_program.rs index ef1e161df4..1187ad8876 100644 --- a/src/serde/deserialize_program.rs +++ b/src/serde/deserialize_program.rs @@ -16,7 +16,7 @@ use crate::{ }, }; use felt::{Felt252, PRIME_STR}; -use num_traits::Num; +use num_traits::{Num, Pow}; use serde::{de, de::MapAccess, de::SeqAccess, Deserialize, Deserializer, Serialize}; use serde_json::Number; @@ -167,7 +167,27 @@ where let n = Number::deserialize(deserializer)?; match Felt252::parse_bytes(n.to_string().as_bytes(), 10) { Some(x) => Ok(Some(x)), - None => Err(String::from("felt_from_number parse error")).map_err(de::Error::custom), + None => { + // Handle de Number with scientific notation cases + // e.g.: Number(1e27) + let str = n.to_string(); + let list: [&str; 2] = str + .split('e') + .collect::>() + .try_into() + .map_err(|_| String::from("felt_from_number parse error")) + .map_err(de::Error::custom)?; + + let base = Felt252::parse_bytes(list[0].to_string().as_bytes(), 10).ok_or( + de::Error::custom(String::from("felt_from_number parse error")), + )?; + let exponent = list[1] + .parse::() + .map_err(|_| de::Error::custom(String::from("felt_from_number parse error")))?; + + let result = base * Felt252::from(10).pow(exponent); + Ok(Some(result)) + } } } @@ -421,6 +441,7 @@ mod tests { use super::*; use assert_matches::assert_matches; use felt::felt_str; + use num_traits::One; use num_traits::Zero; #[cfg(target_arch = "wasm32")] @@ -1363,4 +1384,17 @@ mod tests { let iden: Result = serde_json::from_str(valid_json); assert!(iden.err().is_some()); } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn test_felt_from_number_with_scientific_notation() { + let n = Number::deserialize(serde_json::Value::from(1000000000000000000000000000_u128)) + .unwrap(); + assert_eq!(n.to_string(), "1e27".to_owned()); + + assert_matches!( + felt_from_number(n), + Ok(x) if x == Some(Felt252::one() * Felt252::from(10).pow(27)) + ); + } } From 14af7ef38d3047995b9a94411f70cf7b1cbec463 Mon Sep 17 00:00:00 2001 From: Pedro Fontana Date: Mon, 29 May 2023 18:21:15 -0300 Subject: [PATCH 2/4] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eba913919..d577f87109 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* fix: Handle the deserialization of serde_json::Number with scientific notation (e.g.: Number(1e27)) in felt_from_number function [#1188](https://github.com/lambdaclass/cairo-rs/pull/1188) + * fix: felt_from_number not properly returning parse errors [#1012](https://github.com/lambdaclass/cairo-rs/pull/1012) * fix: Fix felt sqrt and Signed impl [#1150](https://github.com/lambdaclass/cairo-rs/pull/1150) From 98b60bcb3bff807cb46ee7c3ae60dfe3032ccf9c Mon Sep 17 00:00:00 2001 From: Pedro Fontana Date: Mon, 29 May 2023 19:13:27 -0300 Subject: [PATCH 3/4] Add aux function --- src/serde/deserialize_program.rs | 37 ++++++++++++++++---------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/serde/deserialize_program.rs b/src/serde/deserialize_program.rs index 1187ad8876..b668bca04b 100644 --- a/src/serde/deserialize_program.rs +++ b/src/serde/deserialize_program.rs @@ -169,28 +169,29 @@ where Some(x) => Ok(Some(x)), None => { // Handle de Number with scientific notation cases - // e.g.: Number(1e27) - let str = n.to_string(); - let list: [&str; 2] = str - .split('e') - .collect::>() - .try_into() - .map_err(|_| String::from("felt_from_number parse error")) - .map_err(de::Error::custom)?; - - let base = Felt252::parse_bytes(list[0].to_string().as_bytes(), 10).ok_or( - de::Error::custom(String::from("felt_from_number parse error")), - )?; - let exponent = list[1] - .parse::() - .map_err(|_| de::Error::custom(String::from("felt_from_number parse error")))?; - - let result = base * Felt252::from(10).pow(exponent); - Ok(Some(result)) + // e.g.: n = Number(1e27) + let felt = deserialize_scientific_notation(n); + if felt.is_some() { + return Ok(felt); + } + + Err(de::Error::custom(String::from( + "felt_from_number parse error", + ))) } } } +fn deserialize_scientific_notation(n: Number) -> Option { + let str = n.to_string(); + let list: [&str; 2] = str.split('e').collect::>().try_into().ok()?; + + let base = Felt252::parse_bytes(list[0].to_string().as_bytes(), 10)?; + let exponent = list[1].parse::().ok()?; + + let result = base * Felt252::from(10).pow(exponent); + Some(result) +} #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct ReferenceManager { pub references: Vec, From 38e27015a0110236d298645637289bdd2d380d4c Mon Sep 17 00:00:00 2001 From: Pedro Fontana Date: Mon, 29 May 2023 19:13:58 -0300 Subject: [PATCH 4/4] Add endline --- src/serde/deserialize_program.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/serde/deserialize_program.rs b/src/serde/deserialize_program.rs index b668bca04b..ecf0cdf862 100644 --- a/src/serde/deserialize_program.rs +++ b/src/serde/deserialize_program.rs @@ -192,6 +192,7 @@ fn deserialize_scientific_notation(n: Number) -> Option { let result = base * Felt252::from(10).pow(exponent); Some(result) } + #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct ReferenceManager { pub references: Vec,