Skip to content

Commit

Permalink
feat: log/error on mismatch of client version and supported version (#…
Browse files Browse the repository at this point in the history
…1166)

Co-authored-by: hal3e <[email protected]>
Co-authored-by: Ahmed Mujkic <[email protected]>
  • Loading branch information
3 people authored Oct 16, 2023
1 parent 7534c12 commit f12ff73
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ proc-macro2 = "1.0.66"
quote = "1.0.33"
rand = { version = "0.8.5", default-features = false, features = ["std_rng", "getrandom"] }
regex = "1.10.0"
semver = "1.0.20"
serde = { version = "1.0.188", default-features = false }
serde_json = "1.0.107"
serde_with = { version = "3.3.0", default-features = false }
Expand All @@ -64,6 +65,7 @@ tai64 = { version = "4.0.0", default-features = false }
tempfile = { version = "3.8.0", default-features = false }
thiserror = { version = "1.0.49", default-features = false }
tokio = { version = "1.33.0", default-features = false }
tracing = "0.1.37"
trybuild = "1.0.85"
uint = { version = "0.9.5", default-features = false }
which = { version = "4.4.2", default-features = false }
Expand Down
2 changes: 2 additions & 0 deletions packages/fuels-accounts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ fuel-vm = { workspace = true }
fuels-core = { workspace = true }
hex = { workspace = true, default-features = false, features = ["std"] }
rand = { workspace = true, default-features = false }
semver = { workspace = true }
tai64 = { workspace = true, features = ["serde"] }
thiserror = { workspace = true, default-features = false }
tokio = { workspace = true, features = ["full"] }
tracing = { workspace = true }
zeroize = { workspace = true, features = ["derive"] }

[dev-dependencies]
Expand Down
1 change: 1 addition & 0 deletions packages/fuels-accounts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use crate::{accounts_utils::extract_message_id, provider::Provider};
mod accounts_utils;
pub mod predicate;
pub mod provider;
mod supported_versions;
pub mod wallet;

/// Trait for signing transactions and messages
Expand Down
40 changes: 39 additions & 1 deletion packages/fuels-accounts/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ pub use retry_util::{Backoff, RetryConfig};
use tai64::Tai64;
use thiserror::Error;

use crate::provider::retryable_client::RetryableClient;
use crate::{
provider::retryable_client::RetryableClient,
supported_versions::{check_fuel_core_version_compatibility, VersionCompatibility},
};

type ProviderResult<T> = std::result::Result<T, ProviderError>;

#[derive(Debug)]
Expand Down Expand Up @@ -124,6 +128,13 @@ pub enum ProviderError {
ClientRequestError(#[from] io::Error),
#[error("Receipts have not yet been propagated. Retry the request later.")]
ReceiptsNotPropagatedYet,
#[error("Invalid Fuel client version: {0}")]
InvalidFuelClientVersion(#[from] semver::Error),
#[error("Unsupported Fuel client version. Current version: {current}, supported version: {supported}")]
UnsupportedFuelClientVersion {
current: semver::Version,
supported: semver::Version,
},
}

impl From<ProviderError> for Error {
Expand Down Expand Up @@ -269,9 +280,36 @@ impl Provider {
let node_info = self.node_info().await?;
let chain_info = self.chain_info().await?;

Self::ensure_client_version_is_supported(&node_info)?;

Ok(NetworkInfo::new(node_info, chain_info))
}

fn ensure_client_version_is_supported(node_info: &NodeInfo) -> ProviderResult<()> {
let node_version = node_info.node_version.parse::<semver::Version>()?;
let VersionCompatibility {
supported_version,
is_major_supported,
is_minor_supported,
is_patch_supported,
} = check_fuel_core_version_compatibility(node_version.clone());

if !is_major_supported || !is_minor_supported {
return Err(ProviderError::UnsupportedFuelClientVersion {
current: node_version,
supported: supported_version,
});
} else if !is_patch_supported {
tracing::warn!(
fuel_client_version = %node_version,
supported_version = %supported_version,
"The patch versions of the client and SDK differ.",
);
};

Ok(())
}

pub fn chain_id(&self) -> ChainId {
self.consensus_parameters.chain_id
}
Expand Down
116 changes: 116 additions & 0 deletions packages/fuels-accounts/src/supported_versions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
use semver::Version;

fn get_supported_fuel_core_version() -> Version {
"0.20.6".parse().unwrap()
}

#[derive(Debug, PartialEq, Eq)]
pub(crate) struct VersionCompatibility {
pub(crate) supported_version: Version,
pub(crate) is_major_supported: bool,
pub(crate) is_minor_supported: bool,
pub(crate) is_patch_supported: bool,
}

pub(crate) fn check_fuel_core_version_compatibility(
network_version: Version,
) -> VersionCompatibility {
let supported_version = get_supported_fuel_core_version();
check_version_compatibility(network_version, supported_version)
}

fn check_version_compatibility(
actual_version: Version,
expected_version: Version,
) -> VersionCompatibility {
let is_major_supported = expected_version.major == actual_version.major;
let is_minor_supported = expected_version.minor == actual_version.minor;
let is_patch_supported = expected_version.patch == actual_version.patch;

VersionCompatibility {
supported_version: expected_version,
is_major_supported,
is_minor_supported,
is_patch_supported,
}
}

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

#[test]
fn should_validate_all_possible_version_mismatches() {
let expected_version = "0.1.2".parse::<Version>().unwrap();

assert_eq!(
check_version_compatibility("1.1.2".parse().unwrap(), expected_version.clone()),
VersionCompatibility {
is_major_supported: false,
is_minor_supported: true,
is_patch_supported: true,
supported_version: expected_version.clone()
}
);

assert_eq!(
check_version_compatibility("1.2.2".parse().unwrap(), expected_version.clone()),
VersionCompatibility {
is_major_supported: false,
is_minor_supported: false,
is_patch_supported: true,
supported_version: expected_version.clone()
}
);

assert_eq!(
check_version_compatibility("1.1.3".parse().unwrap(), expected_version.clone()),
VersionCompatibility {
is_major_supported: false,
is_minor_supported: true,
is_patch_supported: false,
supported_version: expected_version.clone()
}
);

assert_eq!(
check_version_compatibility("0.2.2".parse().unwrap(), expected_version.clone()),
VersionCompatibility {
is_major_supported: true,
is_minor_supported: false,
is_patch_supported: true,
supported_version: expected_version.clone()
}
);

assert_eq!(
check_version_compatibility("0.2.3".parse().unwrap(), expected_version.clone()),
VersionCompatibility {
is_major_supported: true,
is_minor_supported: false,
is_patch_supported: false,
supported_version: expected_version.clone()
}
);

assert_eq!(
check_version_compatibility("0.1.3".parse().unwrap(), expected_version.clone()),
VersionCompatibility {
is_major_supported: true,
is_minor_supported: true,
is_patch_supported: false,
supported_version: expected_version.clone()
}
);

assert_eq!(
check_version_compatibility("0.1.2".parse().unwrap(), expected_version.clone()),
VersionCompatibility {
is_major_supported: true,
is_minor_supported: true,
is_patch_supported: true,
supported_version: expected_version.clone()
}
);
}
}

0 comments on commit f12ff73

Please sign in to comment.