Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mvr: tests and fixes #23

Merged
merged 1 commit into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions mvr-cli/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions mvr-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ tokio = "1.38.0"
url = "2.5.2"
toml_edit = "0.22.21"
toml = "0.8.19"

[dev-dependencies]
expect-test = "1.1"
162 changes: 71 additions & 91 deletions mvr-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,17 @@ pub enum PackageInfoNetwork {
}

#[derive(Debug)]
struct PackageInfo {
upgrade_cap_id: ObjectID,
package_address: ObjectID,
git_versioning: HashMap<u64, GitInfo>,
pub struct PackageInfo {
pub upgrade_cap_id: ObjectID,
pub package_address: ObjectID,
pub git_versioning: HashMap<u64, GitInfo>,
}

#[derive(Debug)]
struct GitInfo {
repository: String,
tag: String,
path: String,
pub struct GitInfo {
pub repository: String,
pub tag: String,
pub path: String,
}

impl fmt::Display for PackageInfoNetwork {
Expand Down Expand Up @@ -259,7 +259,7 @@ async fn resolve_on_chain_package_info(
Ok(resolved_packages)
}

async fn check_address_consistency(
pub async fn check_address_consistency(
resolved_packages: &HashMap<String, PackageInfo>,
network: &PackageInfoNetwork,
fetched_files: &HashMap<String, (PathBuf, PathBuf)>,
Expand Down Expand Up @@ -287,7 +287,7 @@ async fn check_address_consistency(
anyhow::anyhow!("Failed to retrieve original package address at version 1")
})?
} else {
package_info.package_address.to_string()
package_info.package_address
};

let git_info = package_info.git_versioning.get(&version).ok_or_else(|| {
Expand All @@ -299,7 +299,7 @@ async fn check_address_consistency(

let (move_toml_path, move_lock_path) = fetched_files
.get(name_with_version)
.ok_or_else(|| anyhow!("Failed to find fetched files for {}", name_with_version))?;
.ok_or_else(|| anyhow!("Failed to find fetched files `Move.toml` and `Move.lock when checking address consistency for {}", name_with_version))?;
let move_toml_content = fs::read_to_string(move_toml_path)?;
let move_lock_content = fs::read_to_string(move_lock_path)?;

Expand All @@ -310,11 +310,35 @@ async fn check_address_consistency(
PackageInfoNetwork::Mainnet => MAINNET_CHAIN_ID,
PackageInfoNetwork::Testnet => TESTNET_CHAIN_ID,
};
let address = address
.map(|id_str| {
ObjectID::from_hex_literal(&id_str).map_err(|e| {
anyhow!(
"Failed to parse address in [addresses] section of Move.toml: {}",
e
)
})
})
.transpose()?;
let published_at = published_at
.map(|id_str| {
ObjectID::from_hex_literal(&id_str).map_err(|e| {
anyhow!("Failed to parse published-at address of Move.toml: {}", e)
})
})
.transpose()?;

// The original-published-id may exist in the Move.lock
let original_published_id_in_lock =
get_original_published_id(&move_lock_content, target_chain_id);
get_original_published_id(&move_lock_content, target_chain_id)
.map(|id_str| {
ObjectID::from_hex_literal(&id_str).map_err(|e| {
anyhow!("Failed to parse original-published-id in Move.lock: {}", e)
})
})
.transpose()?;

let (original_source_id, provenance): (String, String) = match (
let (original_source_id, provenance): (ObjectID, String) = match (
original_published_id_in_lock,
published_at,
address,
Expand All @@ -325,22 +349,28 @@ async fn check_address_consistency(
// to reliably identify it by).
// Our best guess is that the published-id refers to the original package (it may not, but
// if it doesn't, there is nowhere else to look in this case).
(published_at_id, "published-at in the Move.toml".into())
(
published_at_id,
"published-at address in the Move.toml".into(),
)
}
(None, Some(published_at_id), Some(address_id))
if address_id == "0x0" || published_at_id == address_id =>
if address_id == ObjectID::ZERO || published_at_id == address_id =>
{
// The [addresses] section has a package name set to "0x0" or the same as the published_at_id.
// Our best guess is that the published-id refers to the original package (it may not, but
// if it doesn't, there is nowhere else to look in this case).
(published_at_id, "published-at in the Move.toml".into())
(
published_at_id,
"published-at address in the Move.toml".into(),
)
}
(None, _, Some(address_id)) => {
// A published-at ID may or may not exist. In either case, it differs from the
// address ID. The address ID that may refer to the original package (e.g., if the
// package was upgraded).
// Our best guess is that the id in the [addresses] section refers to the original ID.
// It may be "0x0" or the original ID
// It may be "0x0" or the original ID.
(
address_id,
"address in the [addresses] section of the Move.toml".into(),
Expand All @@ -361,7 +391,7 @@ async fn check_address_consistency(
// Main consistency check: The on-chain package address should correspond to the original ID in the source package.
if original_address_on_chain != original_source_id {
bail!(
"Mismatch: The original package address for {name} is {original_address_on_chain},\
"Mismatch: The original package address for {name} on {network} is {original_address_on_chain}, \
but the {provenance} in {name}'s repository was found to be {original_source_id}.\n\
Check the configuration of the package's repository {} in branch {} in subdirectory {}",
git_info.repository,
Expand Down Expand Up @@ -413,13 +443,13 @@ async fn get_published_ids(move_toml_content: &str) -> (Option<String>, Option<S
// predictable detection, and the caller can raise an error.
let address = {
// First, check if any address is set to "0x0"
let zero_address = addresses
let package_with_zero_address = addresses
.iter()
.find(|(_, v)| v.as_str() == Some("0x0"))
.map(|(k, _)| k.to_string());

match zero_address {
Some(addr) => Some(addr),
match package_with_zero_address {
Some(_) => Some("0x0".into()),
None => {
let package_name = package_table
.get("name")
Expand Down Expand Up @@ -467,7 +497,7 @@ fn get_original_published_id(move_toml_content: &str, target_chain_id: &str) ->
/// Since we want to communicate `foo` (and the URL where it can be found) to `sui move build`,
/// we create a dependency graph in the `Move.lock` derived from `foo`'s original lock file
/// that contains `foo`. See `insert_root_dependency` for how this works.
async fn build_lock_files(
pub async fn build_lock_files(
resolved_packages: &HashMap<String, PackageInfo>,
fetched_files: &HashMap<String, (PathBuf, PathBuf)>,
) -> Result<Vec<String>> {
Expand All @@ -493,9 +523,13 @@ async fn build_lock_files(
.get(&version)
.ok_or_else(|| anyhow!("version {version} does not exist in on-chain PackageInfo"))?;

let (move_toml_path, move_lock_path) = fetched_files
.get(name_with_version)
.ok_or_else(|| anyhow!("Failed to find fetched files for {}", name_with_version))?;
let (move_toml_path, move_lock_path) =
fetched_files.get(name_with_version).ok_or_else(|| {
anyhow!(
"Failed to find fetched files `Move.toml` and `Move.lock` when building package graph for {}",
name_with_version
)
})?;
let move_toml_content = fs::read_to_string(move_toml_path)?;
let move_lock_content = fs::read_to_string(move_lock_path)?;
let root_name_from_source = parse_source_package_name(&move_toml_content)?;
Expand Down Expand Up @@ -703,7 +737,7 @@ async fn package_at_version(
address: &str,
version: u64,
network: &PackageInfoNetwork,
) -> Result<Option<String>> {
) -> Result<Option<ObjectID>> {
let endpoint = match network {
PackageInfoNetwork::Mainnet => MAINNET_GQL,
PackageInfoNetwork::Testnet => TESTNET_GQL,
Expand Down Expand Up @@ -733,6 +767,16 @@ async fn package_at_version(
let result = body["data"]["package"]["packageAtVersion"]["address"]
.as_str()
.map(String::from);
let result = result
.map(|id_str| {
ObjectID::from_hex_literal(&id_str).map_err(|e| {
anyhow!(
"Failed to parse package address for packageAtVersion GQL request: {}",
e
)
})
})
.transpose()?;
Ok(result)
}

Expand Down Expand Up @@ -777,7 +821,7 @@ fn extract_git_info(dynamic_field_data: &SuiObjectResponse) -> Result<GitInfo> {
}

/// Given a normalized Move Registry package name, split out the version number (if any).
fn parse_package_version(name: &str) -> anyhow::Result<(String, Option<u64>)> {
pub fn parse_package_version(name: &str) -> anyhow::Result<(String, Option<u64>)> {
let parts: Vec<&str> = name.split('/').collect();
match parts.as_slice() {
[base_org, base_name] => Ok((
Expand Down Expand Up @@ -963,70 +1007,6 @@ fn parse_source_package_name(toml_content: &str) -> Result<String> {
Ok(name.to_string())
}

fn _demo_package_move_toml() -> String {
String::from(
r#"[package]
name = "demo"
edition = "2024.beta"

[dependencies]
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "framework/testnet" }

[addresses]
demo = "0x0"

[dev-dependencies]

[dev-addresses]
"#,
)
}

fn _demo_package_move_lock() -> String {
String::from(
r#"# @generated by Move, please check-in and do not edit manually.

[move]
version = 2
manifest_digest = "72EAB20899F5ADF42787258ACEE32F8531E06BB319B82DFA6866FA4807AAC42E"
deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082"
dependencies = [
{ name = "Sui" },
]

[[move.package]]
name = "MoveStdlib"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/move-stdlib" }

[[move.package]]
name = "Sui"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/sui-framework" }

dependencies = [
{ name = "MoveStdlib" },
]

[move.toolchain-version]
compiler-version = "1.33.0"
edition = "2024.beta"
flavor = "sui"

[env]

[env.testnet]
chain-id = "4c78adac"
original-published-id = "0x2c6aa312fbba13c0184b10a53273b58fda1e9f6119ce8a55fd2d7ea452c56bd8"
latest-published-id = "0x2c6aa312fbba13c0184b10a53273b58fda1e9f6119ce8a55fd2d7ea452c56bd8"
published-version = "1"

[env.mainnet]
chain-id = "35834a8a"
original-published-id = "0x6ad6692327074e360e915401812aa3192e88f6effb02b3d67a970e57dd11f1b0"
latest-published-id = "0x6ad6692327074e360e915401812aa3192e88f6effb02b3d67a970e57dd11f1b0"
published-version = "1""#,
)
}

fn update_mvr_packages(move_toml_path: &Path, package_name: &str, network: &str) -> Result<()> {
let toml_content = fs::read_to_string(&move_toml_path)
.with_context(|| format!("Failed to read file: {:?}", move_toml_path))?;
Expand Down
Loading