Skip to content

Commit 25d1042

Browse files
MaksymMalickirodrigo-pino
authored andcommitted
refactor(vm): refactor loading of the versioned constants (#2666)
modify the versioned constants handling Co-authored-by: Rodrigo <rodrodpino@gmail.com>
1 parent e634093 commit 25d1042

File tree

4 files changed

+77
-18
lines changed

4 files changed

+77
-18
lines changed

vm/rust/src/lib.rs

+64-16
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ use std::{
1414
ffi::{c_char, c_longlong, c_uchar, c_ulonglong, c_void, CStr, CString},
1515
slice,
1616
sync::Arc,
17+
collections::BTreeMap,
18+
fs::File,
19+
io::Read,
20+
path::Path,
1721
};
1822

1923
use anyhow::Result;
@@ -63,6 +67,14 @@ use starknet_api::{
6367
use starknet_types_core::felt::Felt;
6468
use std::str::FromStr;
6569
type StarkFelt = Felt;
70+
use once_cell::sync::Lazy;
71+
use anyhow::Context;
72+
73+
// Allow users to call CONSTRUCTOR entry point type which has fixed entry_point_felt "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194"
74+
pub static CONSTRUCTOR_ENTRY_POINT_FELT: Lazy<StarkFelt> = Lazy::new(|| {
75+
StarkFelt::from_hex("0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194")
76+
.expect("Invalid hex string")
77+
});
6678

6779
extern "C" {
6880
fn JunoReportError(
@@ -695,21 +707,48 @@ fn build_block_context(
695707

696708
#[allow(static_mut_refs)]
697709
fn get_versioned_constants(version: *const c_char) -> VersionedConstants {
698-
if let Some(constants) = unsafe { &CUSTOM_VERSIONED_CONSTANTS } {
699-
return constants.clone();
700-
}
710+
let starknet_version = unsafe { CStr::from_ptr(version) }.to_str()
711+
.ok()
712+
.and_then(|version_str| StarknetVersion::try_from(version_str).ok());
701713

702-
let version_str = unsafe { CStr::from_ptr(version) }.to_str();
714+
if let (Some(custom_constants), Some(version)) = (unsafe { &CUSTOM_VERSIONED_CONSTANTS }, starknet_version) {
715+
if let Some(constants) = custom_constants.0.get(&version) {
716+
return constants.clone();
717+
}
718+
}
703719

704-
version_str
705-
.ok()
706-
.and_then(|version| StarknetVersion::try_from(version).ok())
720+
starknet_version
707721
.and_then(|version| VersionedConstants::get(&version).ok())
708722
.unwrap_or(VersionedConstants::latest_constants())
709723
.to_owned()
710724
}
711725

712-
static mut CUSTOM_VERSIONED_CONSTANTS: Option<VersionedConstants> = None;
726+
#[derive(Debug)]
727+
pub struct VersionedConstantsMap(pub BTreeMap<StarknetVersion, VersionedConstants>);
728+
729+
impl VersionedConstantsMap {
730+
pub fn from_file(version_with_path: BTreeMap<String, String>) -> Result<Self> {
731+
let mut result = BTreeMap::new();
732+
733+
for (version, path) in version_with_path {
734+
let mut file = File::open(Path::new(&path)).with_context(|| format!("Failed to open file: {}", path))?;
735+
736+
let mut contents = String::new();
737+
file.read_to_string(&mut contents).with_context(|| format!("Failed to read contents of file: {}", path))?;
738+
739+
let constants: VersionedConstants =
740+
serde_json::from_str(&contents).with_context(|| format!("Failed to parse JSON in file: {}", path))?;
741+
742+
let parsed_version = StarknetVersion::try_from(version.as_str()).with_context(|| format!("Failed to parse version string: {}", version))?;
743+
744+
result.insert(parsed_version, constants);
745+
}
746+
747+
Ok(VersionedConstantsMap(result))
748+
}
749+
}
750+
751+
static mut CUSTOM_VERSIONED_CONSTANTS: Option<VersionedConstantsMap> = None;
713752

714753
#[no_mangle]
715754
#[allow(clippy::not_unsafe_ptr_arg_deref)]
@@ -725,14 +764,23 @@ pub extern "C" fn setVersionedConstants(json_bytes: *const c_char) -> *const c_c
725764
}
726765
};
727766

728-
match serde_json::from_str::<VersionedConstants>(json_str) {
729-
Ok(parsed) => unsafe {
730-
CUSTOM_VERSIONED_CONSTANTS = Some(parsed);
731-
CString::new("").unwrap().into_raw() // No error, return an empty string
732-
},
733-
Err(e) => CString::new(format!("Failed to parse JSON: {}", e))
734-
.unwrap()
735-
.into_raw(),
767+
let versioned_constants_files_paths: Result<BTreeMap<String, String>, _> = serde_json::from_str(json_str);
768+
if let Ok(paths) = versioned_constants_files_paths {
769+
match VersionedConstantsMap::from_file(paths) {
770+
Ok(custom_constants) => {
771+
unsafe {
772+
CUSTOM_VERSIONED_CONSTANTS = Some(custom_constants);
773+
return CString::new("").unwrap().into_raw();
774+
}
775+
},
776+
Err(e) => {
777+
return CString::new(format!("Failed to load versioned constants from paths: {}", e))
778+
.unwrap()
779+
.into_raw();
780+
}
781+
}
782+
} else {
783+
return CString::new("Failed to parse JSON").unwrap().into_raw();
736784
}
737785
}
738786

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"0.13.2": "./testdata/versioned_constants/0_13_2.json"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"0.13.2": "./testdata/versioned_constants/0_13_2.json",
3+
"0.13.2.1": "./testdata/versioned_constants/0_13_2.json"
4+
}

vm/vm_test.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,12 @@ func TestExecute(t *testing.T) {
276276
}
277277

278278
func TestSetVersionedConstants(t *testing.T) {
279-
t.Run("valid json", func(t *testing.T) {
280-
require.NoError(t, SetVersionedConstants("testdata/versioned_constants/0_13_2.json"))
279+
t.Run("valid custom versioned constants file (1 overwrite)", func(t *testing.T) {
280+
require.NoError(t, SetVersionedConstants("testdata/versioned_constants/custom_versioned_constants.json"))
281+
})
282+
283+
t.Run("valid custom versioned constants file (multiple overwrites)", func(t *testing.T) {
284+
require.NoError(t, SetVersionedConstants("testdata/versioned_constants/custom_versioned_constants_multiple.json"))
281285
})
282286

283287
t.Run("not valid json", func(t *testing.T) {

0 commit comments

Comments
 (0)