Skip to content

Commit

Permalink
chore: wrap cairo lang version id for code dedup (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArniStarkware authored Aug 18, 2024
1 parent a37bcb6 commit 7e067de
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 98 deletions.
83 changes: 36 additions & 47 deletions crates/gateway/src/compiler_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use serde::{Deserialize, Serialize};
use starknet_sierra_compile::utils::sierra_program_as_felts_to_big_uint_as_hex;
use starknet_types_core::felt::Felt;
use thiserror::Error;
use validator::Validate;

#[derive(Debug, Error)]
#[cfg_attr(test, derive(PartialEq))]
Expand All @@ -19,52 +18,34 @@ pub enum VersionIdError {
InvalidVersion { message: String },
}

// TODO(Arni): Share this struct with the Cairo lang crate.
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Validate, PartialEq)]
pub struct VersionId {
pub major: usize,
pub minor: usize,
pub patch: usize,
}

impl VersionId {
pub const MIN: Self = Self { major: 0, minor: 0, patch: 0 };
pub const MAX: Self = Self { major: usize::MAX, minor: usize::MAX, patch: usize::MAX };
}

impl From<VersionId> for CairoLangVersionId {
fn from(version: VersionId) -> Self {
CairoLangVersionId { major: version.major, minor: version.minor, patch: version.patch }
}
}

impl From<CairoLangVersionId> for VersionId {
fn from(version: CairoLangVersionId) -> Self {
VersionId { major: version.major, minor: version.minor, patch: version.patch }
}
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
pub struct VersionId(pub CairoLangVersionId);

impl std::fmt::Display for VersionId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
CairoLangVersionId::from(*self).fmt(f)
self.0.fmt(f)
}
}

impl VersionId {
pub fn from_sierra_program(sierra_program: &[Felt]) -> Result<Self, VersionIdError> {
let sierra_program_length = sierra_program.len();
pub const MIN: Self = Self(CairoLangVersionId { major: 0, minor: 0, patch: 0 });
pub const MAX: Self =
Self(CairoLangVersionId { major: usize::MAX, minor: usize::MAX, patch: usize::MAX });

pub fn new(major: usize, minor: usize, patch: usize) -> Self {
Self(CairoLangVersionId { major, minor, patch })
}

if sierra_program_length < 6 {
return Err(VersionIdError::InvalidVersion {
pub fn from_sierra_program(sierra_program: &[Felt]) -> Result<Self, VersionIdError> {
let sierra_program_for_compiler = sierra_program_as_felts_to_big_uint_as_hex(
sierra_program.get(..6).ok_or(VersionIdError::InvalidVersion {
message: format!(
"Sierra program is too short. Got program of length {}, which is not long \
enough for Sierra program's headers.",
sierra_program_length
"Failed to retrieve version from the program: insufficient length. Expected \
at least 6 felts (got {}).",
sierra_program.len()
),
});
}
let sierra_program_for_compiler =
sierra_program_as_felts_to_big_uint_as_hex(&sierra_program[..6]);
})?,
);

let (version_id, _compiler_version_id) = version_id_from_serialized_sierra_program(
&sierra_program_for_compiler,
Expand All @@ -73,19 +54,27 @@ impl VersionId {
message: format!("Error extracting version ID from Sierra program: {err}"),
})?;

Ok(version_id.into())
Ok(VersionId(version_id))
}
}

impl PartialOrd for VersionId {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
if self.major != other.major {
return Some(self.major.cmp(&other.major));
// An implementation of partial_cmp for VersionId.
fn partial_cmp(
lhs: &CairoLangVersionId,
rhs: &CairoLangVersionId,
) -> Option<std::cmp::Ordering> {
if lhs.major != rhs.major {
return Some(lhs.major.cmp(&rhs.major));
}
if lhs.minor != rhs.minor {
return Some(lhs.minor.cmp(&rhs.minor));
}
lhs.patch.partial_cmp(&rhs.patch)
}
if self.minor != other.minor {
return Some(self.minor.cmp(&other.minor));
}
self.patch.partial_cmp(&other.patch)

partial_cmp(&self.0, &other.0)
}
}

Expand All @@ -94,19 +83,19 @@ impl SerializeConfig for VersionId {
BTreeMap::from_iter([
ser_param(
"major",
&self.major,
&self.0.major,
"The major version of the configuration.",
ParamPrivacyInput::Public,
),
ser_param(
"minor",
&self.minor,
&self.0.minor,
"The minor version of the configuration.",
ParamPrivacyInput::Public,
),
ser_param(
"patch",
&self.patch,
&self.0.patch,
"The patch version of the configuration.",
ParamPrivacyInput::Public,
),
Expand Down
4 changes: 2 additions & 2 deletions crates/gateway/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ impl Default for StatelessTransactionValidatorConfig {
max_calldata_length: 4000,
max_signature_length: 4000,
max_contract_class_object_size: 4089446,
min_sierra_version: VersionId { major: 1, minor: 1, patch: 0 },
max_sierra_version: VersionId { major: 1, minor: 5, patch: usize::MAX },
min_sierra_version: VersionId::new(1, 1, 0),
max_sierra_version: VersionId::new(1, 5, usize::MAX),
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion crates/gateway/src/stateless_transaction_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ impl StatelessTransactionValidator {
) -> StatelessTransactionValidatorResult<()> {
// Any patch version is valid. (i.e. when check version for upper bound, we ignore the Z
// part in a version X.Y.Z).
let max_sierra_version = VersionId { patch: usize::MAX, ..self.config.max_sierra_version };
let mut max_sierra_version = self.config.max_sierra_version;
max_sierra_version.0.patch = usize::MAX;

let sierra_version = VersionId::from_sierra_program(sierra_program)?;
if self.config.min_sierra_version <= sierra_version && sierra_version <= max_sierra_version
Expand Down
Loading

0 comments on commit 7e067de

Please sign in to comment.