Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix felt serialization in snforge-test-collector #1318

Merged
merged 1 commit into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::felt252::Felt252;
use anyhow::Result;
use cairo_lang_defs::plugin::PluginDiagnostic;
use cairo_lang_diagnostics::Severity;
Expand All @@ -12,7 +13,6 @@ use cairo_lang_utils::OptionHelper;
use num_bigint::BigInt;
use num_traits::ToPrimitive;
use serde::Serialize;
use starknet_types_core::felt::Felt as Felt252;
use std::num::NonZeroU32;

const FORK_ATTR: &str = "fork";
Expand All @@ -31,7 +31,9 @@ impl From<PanicExpectation> for ExpectedPanicValue {
fn from(value: PanicExpectation) -> Self {
match value {
PanicExpectation::Any => ExpectedPanicValue::Any,
PanicExpectation::Exact(vec) => ExpectedPanicValue::Exact(vec),
PanicExpectation::Exact(vec) => {
ExpectedPanicValue::Exact(vec.into_iter().map(Felt252::new).collect())
}
}
}
}
Expand Down
81 changes: 81 additions & 0 deletions extensions/scarb-snforge-test-collector/src/felt252.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use serde::{
ser::{SerializeMap, SerializeSeq},
Serialize, Serializer,
};
use std::collections::HashMap;

#[derive(Debug, Clone, PartialEq)]
pub struct Felt252(WrapperInner);

impl Felt252 {
pub fn new(felt: starknet_types_core::felt::Felt) -> Self {
Self(WrapperInner(felt))
}
}

#[derive(Debug, Clone, PartialEq)]
struct WrapperInner(starknet_types_core::felt::Felt);

impl Serialize for Felt252 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let sub_map: HashMap<_, _> = [("val", self.0.clone())].into_iter().collect();

let mut map = serializer.serialize_map(Some(1))?;
map.serialize_entry("value", &sub_map)?;
map.end()
}
}

// this is copy-pasted BigUint (old felt implementation) inner serialization with inlining
impl Serialize for WrapperInner {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut data: Vec<_> = self
.0
.to_bytes_le()
.chunks(8)
.map(|chunk| {
chunk
.iter()
.rev()
.fold(0, |acc, &c| (acc << 8) | u64::from(c))
})
.collect();

normalize(&mut data);

if let Some((&last, data)) = data.split_last() {
let last_lo = last as u32;
let last_hi = (last >> 32) as u32;
let u32_len = data.len() * 2 + 1 + (last_hi != 0) as usize;
let mut seq = serializer.serialize_seq(Some(u32_len))?;
for &x in data {
seq.serialize_element(&(x as u32))?;
seq.serialize_element(&((x >> 32) as u32))?;
}
seq.serialize_element(&last_lo)?;
if last_hi != 0 {
seq.serialize_element(&last_hi)?;
}
seq.end()
} else {
let data: &[u32] = &[];
data.serialize(serializer)
}
}
}

fn normalize(data: &mut Vec<u64>) {
if let Some(&0) = data.last() {
let len = data.iter().rposition(|&d| d != 0).map_or(0, |i| i + 1);
data.truncate(len);
}
if data.len() < data.capacity() / 4 {
data.shrink_to_fit();
}
}
1 change: 1 addition & 0 deletions extensions/scarb-snforge-test-collector/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::metadata::compilation_unit_for_package;

mod compilation;
mod crate_collection;
mod felt252;
mod metadata;

/// Starknet Foundry private extension for compiling test artifacts.
Expand Down
1 change: 0 additions & 1 deletion extensions/scarb-snforge-test-collector/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,6 @@ const SHOULD_PANIC_TEST: &str = indoc! {r#"
};

#[test]
#[ignore = "TODO: fix felt serialization"]
fn forge_test_with_should_panic_message_attribute() {
let t = TempDir::new().unwrap();
let pkg1 = t.child("forge");
Expand Down
Loading