diff --git a/crates/sui-protocol-config/src/lib.rs b/crates/sui-protocol-config/src/lib.rs index 54ee7bee79f5a5..8e0447344b0930 100644 --- a/crates/sui-protocol-config/src/lib.rs +++ b/crates/sui-protocol-config/src/lib.rs @@ -257,16 +257,6 @@ impl Chain { Chain::Unknown => "unknown", } } - - /// Convert a four byte chain ID digest string to a Chain enum. - /// necessary for use with sui_getChainIdentifier JSON RPC - pub fn from_chain_id(chain_id: String) -> Self { - match chain_id.as_str() { - "35834a8a" => Chain::Mainnet, - "4c78adac" => Chain::Testnet, - _ => Chain::Unknown, - } - } } pub struct Error(pub String); diff --git a/crates/sui-types/src/digests.rs b/crates/sui-types/src/digests.rs index 52444720d158d7..58abd358264cfd 100644 --- a/crates/sui-types/src/digests.rs +++ b/crates/sui-types/src/digests.rs @@ -4,7 +4,7 @@ use std::{env, fmt}; use crate::{error::SuiError, sui_serde::Readable}; -use fastcrypto::encoding::{Base58, Encoding}; +use fastcrypto::encoding::{Base58, Encoding, Hex}; use once_cell::sync::{Lazy, OnceCell}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -157,6 +157,10 @@ impl fmt::UpperHex for Digest { )] pub struct ChainIdentifier(CheckpointDigest); + +pub const MAINNET_CHAIN_IDENTIFIER_BASE58: &str = "4btiuiMPvEENsttpZC7CZ53DruC3MAgfznDbASZ7DR6S"; +pub const TESTNET_CHAIN_IDENTIFIER_BASE58: &str = "69WiPg3DAQiwdxfncX6wYQ2siKwAe6L9BZthQea3JNMD"; + pub static MAINNET_CHAIN_IDENTIFIER: OnceCell = OnceCell::new(); pub static TESTNET_CHAIN_IDENTIFIER: OnceCell = OnceCell::new(); @@ -178,7 +182,22 @@ static SUI_PROTOCOL_CONFIG_CHAIN_OVERRIDE: Lazy> = Lazy::new(|| { } }); + impl ChainIdentifier { + /// take a short 4 byte identifier and convert it into a ChainIdentifier + /// short ids come from the JSON RPC getChainIdentifier and are encoded in hex + pub fn from_chain_short_id(short_id: &String) -> Option { + if Hex::from_bytes(&Base58::decode(MAINNET_CHAIN_IDENTIFIER_BASE58).ok()?).encoded_with_format() + .starts_with(&format!("0x{}", short_id)) { + Some(get_mainnet_chain_identifier()) + } else if Hex::from_bytes(&Base58::decode(TESTNET_CHAIN_IDENTIFIER_BASE58).ok()?).encoded_with_format() + .starts_with(&format!("0x{}", short_id)) { + Some(get_testnet_chain_identifier()) + } else { + None + } + } + pub fn chain(&self) -> Chain { let mainnet_id = get_mainnet_chain_identifier(); let testnet_id = get_testnet_chain_identifier(); @@ -203,10 +222,11 @@ impl ChainIdentifier { } } + pub fn get_mainnet_chain_identifier() -> ChainIdentifier { let digest = MAINNET_CHAIN_IDENTIFIER.get_or_init(|| { let digest = CheckpointDigest::new( - Base58::decode("4btiuiMPvEENsttpZC7CZ53DruC3MAgfznDbASZ7DR6S") + Base58::decode(MAINNET_CHAIN_IDENTIFIER_BASE58) .expect("mainnet genesis checkpoint digest literal is invalid") .try_into() .expect("Mainnet genesis checkpoint digest literal has incorrect length"), @@ -219,7 +239,7 @@ pub fn get_mainnet_chain_identifier() -> ChainIdentifier { pub fn get_testnet_chain_identifier() -> ChainIdentifier { let digest = TESTNET_CHAIN_IDENTIFIER.get_or_init(|| { let digest = CheckpointDigest::new( - Base58::decode("69WiPg3DAQiwdxfncX6wYQ2siKwAe6L9BZthQea3JNMD") + Base58::decode(TESTNET_CHAIN_IDENTIFIER_BASE58) .expect("testnet genesis checkpoint digest literal is invalid") .try_into() .expect("Testnet genesis checkpoint digest literal has incorrect length"), @@ -1043,3 +1063,26 @@ impl fmt::Debug for ConsensusCommitDigest { .finish() } } + + +mod test { + use crate::digests::ChainIdentifier; + // check that the chain id returns mainnet + #[test] + fn test_chain_id_mainnet() { + let chain_id = ChainIdentifier::from_chain_short_id(&String::from("35834a8a")); + assert_eq!(chain_id.unwrap().chain(), sui_protocol_config::Chain::Mainnet); + } + + #[test] + fn test_chain_id_testnet() { + let chain_id = ChainIdentifier::from_chain_short_id(&String::from("4c78adac")); + assert_eq!(chain_id.unwrap().chain(), sui_protocol_config::Chain::Testnet); + } + + #[test] + fn test_chain_id_unknown() { + let chain_id = ChainIdentifier::from_chain_short_id(&String::from("unknown")); + assert_eq!(chain_id, None); + } +} \ No newline at end of file diff --git a/crates/sui/src/client_commands.rs b/crates/sui/src/client_commands.rs index 2d191b4c3d2a83..5e3d84a34d3fe5 100644 --- a/crates/sui/src/client_commands.rs +++ b/crates/sui/src/client_commands.rs @@ -95,6 +95,7 @@ use tabled::{ }; use tracing::{debug, info}; +use sui_types::digests::ChainIdentifier; #[path = "unit_tests/profiler_tests.rs"] #[cfg(test)] @@ -867,8 +868,12 @@ impl SuiClientCommands { let sender = sender.unwrap_or(context.active_address()?); let client = context.get_client().await?; let chain_id = client.read_api().get_chain_identifier().await.ok(); - let protocol_config = - ProtocolConfig::get_for_version(ProtocolVersion::MAX, Chain::Unknown); + let protocol_config = ProtocolConfig::get_for_version( + ProtocolVersion::MAX, match &chain_id + .and_then(|id| ChainIdentifier::from_chain_short_id(&id)) { + Some(chain_id) => chain_id.chain(), + None => Chain::Unknown, + }); let package_path = package_path