Skip to content

Commit

Permalink
fix: add more logic on semver check of Starknet API (#1966)
Browse files Browse the repository at this point in the history
* fix: add more logic on semver check of Starknet API

* fix: use matches functionality from semver crate

* fix: fix typo
  • Loading branch information
glihm authored May 16, 2024
1 parent 628542f commit 543322b
Showing 1 changed file with 68 additions and 2 deletions.
70 changes: 68 additions & 2 deletions bin/sozo/src/commands/migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@ pub async fn setup_env<'a>(

let (account, rpc_url) = {
let provider = starknet.provider(env)?;
trace!("Provider initialized.");
trace!(?provider, "Provider initialized.");

let spec_version = provider.spec_version().await?;
trace!(spec_version);

if spec_version != RPC_SPEC_VERSION {
if !is_compatible_version(&spec_version, RPC_SPEC_VERSION)? {
return Err(anyhow!(
"Unsupported Starknet RPC version: {}, expected {}.",
spec_version,
Expand Down Expand Up @@ -167,3 +167,69 @@ pub async fn setup_env<'a>(

Ok((world_address, account, rpc_url.to_string()))
}

/// Checks if the provided version string is compatible with the expected version string using
/// semantic versioning rules. Includes specific backward compatibility rules, e.g., version 0.6 is
/// compatible with 0.7.
///
/// # Arguments
///
/// * `provided_version` - The version string provided by the user.
/// * `expected_version` - The expected version string.
///
/// # Returns
///
/// * `Result<bool>` - Returns `true` if the provided version is compatible with the expected
/// version, `false` otherwise.
fn is_compatible_version(provided_version: &str, expected_version: &str) -> Result<bool> {
use semver::{Version, VersionReq};

let provided_ver = Version::parse(provided_version)
.map_err(|e| anyhow!("Failed to parse provided version '{}': {}", provided_version, e))?;
let expected_ver = Version::parse(expected_version)
.map_err(|e| anyhow!("Failed to parse expected version '{}': {}", expected_version, e))?;

// Specific backward compatibility rule: 0.6 is compatible with 0.7.
if (provided_ver.major == 0 && provided_ver.minor == 6)
&& (expected_ver.major == 0 && expected_ver.minor == 7)
{
return Ok(true);
}

let expected_ver_req = VersionReq::parse(expected_version).map_err(|e| {
anyhow!("Failed to parse expected version requirement '{}': {}", expected_version, e)
})?;

Ok(expected_ver_req.matches(&provided_ver))
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_is_compatible_version_major_mismatch() {
assert!(!is_compatible_version("1.0.0", "2.0.0").unwrap());
}

#[test]
fn test_is_compatible_version_minor_compatible() {
assert!(is_compatible_version("1.2.0", "1.1.0").unwrap());
}

#[test]
fn test_is_compatible_version_minor_mismatch() {
assert!(!is_compatible_version("0.2.0", "0.7.0").unwrap());
}

#[test]
fn test_is_compatible_version_specific_backward_compatibility() {
assert!(is_compatible_version("0.6.0", "0.7.1").unwrap());
}

#[test]
fn test_is_compatible_version_invalid_version_string() {
assert!(is_compatible_version("1.0", "1.0.0").is_err());
assert!(is_compatible_version("1.0.0", "1.0").is_err());
}
}

0 comments on commit 543322b

Please sign in to comment.