From 9cdec4fec1895bb3cc9996fe842bf50c24753cf2 Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Thu, 20 Oct 2022 15:15:34 -0400 Subject: [PATCH] [move] introduce Sui variant of CompiledPackage - Add a Sui wrapper around the Move CompiledPackage so we can add extra metadata and traits - Use this to clean up the build API's, which previously made it very hard for clients to get a package and led to a lot of code duplication - Did this because I'm looking at generating Move struct layout files to be consumed by SDK's like the TS SDK, but was finding it hard to get my hands on the package object --- Cargo.lock | 14 +- crates/sui-core/Cargo.toml | 2 +- .../unit_tests/authority_aggregator_tests.rs | 16 +- .../src/unit_tests/authority_tests.rs | 11 +- .../src/unit_tests/gateway_state_tests.rs | 15 +- .../src/unit_tests/move_integration_tests.rs | 15 +- crates/sui-framework-build/Cargo.toml | 2 +- .../src/compiled_package.rs | 271 ++++++++++++++++++ crates/sui-framework-build/src/lib.rs | 105 +------ crates/sui-framework/Cargo.toml | 7 +- crates/sui-framework/build.rs | 56 ++-- crates/sui-framework/src/lib.rs | 137 ++------- crates/sui-gateway/Cargo.toml | 3 +- .../src/unit_tests/rpc_server_tests.rs | 15 +- crates/sui-json/Cargo.toml | 3 +- crates/sui-json/src/tests.rs | 13 +- crates/sui/Cargo.toml | 1 + crates/sui/src/client_commands.rs | 17 +- crates/sui/src/sui_move/build.rs | 27 +- crates/test-utils/Cargo.toml | 2 +- crates/test-utils/src/messages.rs | 27 +- crates/test-utils/src/transaction.rs | 15 +- 22 files changed, 419 insertions(+), 355 deletions(-) create mode 100644 crates/sui-framework-build/src/compiled_package.rs diff --git a/Cargo.lock b/Cargo.lock index 92ef13bd3bdb3..5ac81414cf590 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8041,6 +8041,7 @@ dependencies = [ "sui-config", "sui-core", "sui-framework", + "sui-framework-build", "sui-json", "sui-json-rpc-types", "sui-keys", @@ -8229,7 +8230,6 @@ dependencies = [ "move-binary-format", "move-bytecode-utils", "move-core-types", - "move-package", "move-vm-runtime", "multiaddr", "mysten-network", @@ -8254,6 +8254,7 @@ dependencies = [ "sui-adapter", "sui-config", "sui-framework", + "sui-framework-build", "sui-json", "sui-json-rpc-types", "sui-macros", @@ -8357,7 +8358,6 @@ dependencies = [ "fastcrypto", "linked-hash-map", "move-binary-format", - "move-bytecode-utils", "move-bytecode-verifier", "move-cli", "move-compiler", @@ -8375,7 +8375,6 @@ dependencies = [ "smallvec", "sui-framework-build", "sui-types", - "sui-verifier", "workspace-hack", ] @@ -8383,6 +8382,7 @@ dependencies = [ name = "sui-framework-build" version = "0.0.0" dependencies = [ + "anyhow", "move-binary-format", "move-bytecode-utils", "move-bytecode-verifier", @@ -8403,13 +8403,12 @@ dependencies = [ "async-trait", "clap 3.2.22", "futures", - "move-package", "mysten-network", "prometheus", "serde 1.0.147", "sui-config", "sui-core", - "sui-framework", + "sui-framework-build", "sui-json", "sui-json-rpc", "sui-json-rpc-types", @@ -8433,12 +8432,11 @@ dependencies = [ "hex", "move-binary-format", "move-core-types", - "move-package", "schemars", "serde 1.0.147", "serde_json", "sui-adapter", - "sui-framework", + "sui-framework-build", "sui-types", "sui-verifier", "test-fuzz", @@ -9193,7 +9191,6 @@ dependencies = [ "jsonrpsee", "jsonrpsee-http-client", "move-core-types", - "move-package", "multiaddr", "mysten-network", "once_cell", @@ -9206,6 +9203,7 @@ dependencies = [ "sui-config", "sui-core", "sui-framework", + "sui-framework-build", "sui-json-rpc", "sui-json-rpc-types", "sui-keys", diff --git a/crates/sui-core/Cargo.toml b/crates/sui-core/Cargo.toml index 15cc7078f1858..55efb490c6731 100644 --- a/crates/sui-core/Cargo.toml +++ b/crates/sui-core/Cargo.toml @@ -68,13 +68,13 @@ sui-macros = { path = "../sui-macros" } [dev-dependencies] clap = { version = "3.2.17", features = ["derive"] } rand = "0.8.5" -move-package.workspace = true serde-reflection = "0.3.6" serde_yaml = "0.8.26" pretty_assertions = "1.2.1" telemetry-subscribers.workspace = true +sui-framework-build = { path = "../sui-framework-build" } sui-macros = { path = "../sui-macros" } test-fuzz = "3.0.4" diff --git a/crates/sui-core/src/unit_tests/authority_aggregator_tests.rs b/crates/sui-core/src/unit_tests/authority_aggregator_tests.rs index cf37f15ac9732..8153088b48cb8 100644 --- a/crates/sui-core/src/unit_tests/authority_aggregator_tests.rs +++ b/crates/sui-core/src/unit_tests/authority_aggregator_tests.rs @@ -3,13 +3,13 @@ use bcs::to_bytes; use move_core_types::{account_address::AccountAddress, ident_str}; -use move_package::BuildConfig; use multiaddr::Multiaddr; use std::collections::BTreeMap; use std::path::PathBuf; use std::sync::{Arc, Mutex}; use sui_config::genesis::Genesis; use sui_config::ValidatorInfo; +use sui_framework_build::compiled_package::BuildConfig; use sui_network::{DEFAULT_CONNECT_TIMEOUT_SEC, DEFAULT_REQUEST_TIMEOUT_SEC}; use sui_types::crypto::{ generate_proof_of_possession, get_authority_key_pair, get_key_pair, AccountKeyPair, @@ -80,7 +80,12 @@ pub async fn init_local_authorities( let build_config = BuildConfig::default(); let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("src/unit_tests/data/object_basics"); - let modules = sui_framework::build_move_package(&path, build_config).unwrap(); + let modules = sui_framework::build_move_package(&path, build_config) + .unwrap() + .get_modules() + .into_iter() + .cloned() + .collect(); let pkg = Object::new_package(modules, TransactionDigest::genesis()); let pkg_ref = pkg.compute_object_reference(); genesis_objects.push(pkg); @@ -436,7 +441,12 @@ async fn test_quorum_map_and_reduce_timeout() { let build_config = BuildConfig::default(); let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("src/unit_tests/data/object_basics"); - let modules = sui_framework::build_move_package(&path, build_config).unwrap(); + let modules = sui_framework::build_move_package(&path, build_config) + .unwrap() + .get_modules() + .into_iter() + .cloned() + .collect(); let pkg = Object::new_package(modules, TransactionDigest::genesis()); let pkg_ref = pkg.compute_object_reference(); let (addr1, key1): (_, AccountKeyPair) = get_key_pair(); diff --git a/crates/sui-core/src/unit_tests/authority_tests.rs b/crates/sui-core/src/unit_tests/authority_tests.rs index 74ccfea4421e2..aa37a0b623b31 100644 --- a/crates/sui-core/src/unit_tests/authority_tests.rs +++ b/crates/sui-core/src/unit_tests/authority_tests.rs @@ -2031,7 +2031,7 @@ pub async fn init_state_with_ids_and_object_basics< >( objects: I, ) -> (AuthorityState, ObjectRef) { - use move_package::BuildConfig; + use sui_framework_build::compiled_package::BuildConfig; let state = init_state().await; for (address, object_id) in objects { @@ -2040,10 +2040,15 @@ pub async fn init_state_with_ids_and_object_basics< } // add object_basics package object to genesis, since lots of test use it - let build_config = BuildConfig::default(); let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("src/unit_tests/data/object_basics"); - let modules = sui_framework::build_move_package(&path, build_config).unwrap(); + let modules = BuildConfig::default() + .build(path) + .unwrap() + .get_modules() + .into_iter() + .cloned() + .collect(); let pkg = Object::new_package(modules, TransactionDigest::genesis()); let pkg_ref = pkg.compute_object_reference(); state.insert_genesis_object(pkg).await; diff --git a/crates/sui-core/src/unit_tests/gateway_state_tests.rs b/crates/sui-core/src/unit_tests/gateway_state_tests.rs index 22c5814914c77..8a9fdee53bd0f 100644 --- a/crates/sui-core/src/unit_tests/gateway_state_tests.rs +++ b/crates/sui-core/src/unit_tests/gateway_state_tests.rs @@ -2,14 +2,13 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -use move_package::BuildConfig; use serde_json::json; use std::{collections::HashSet, path::Path}; use signature::Signer; use typed_store::Map; -use sui_framework::build_move_package_to_bytes; +use sui_framework_build::compiled_package::BuildConfig; use sui_types::crypto::{AccountKeyPair, Signature}; use sui_types::gas_coin::GasCoin; use sui_types::messages::Transaction; @@ -145,8 +144,10 @@ async fn test_publish() { let mut path = env!("CARGO_MANIFEST_DIR").to_owned(); path.push_str("/src/unit_tests/data/object_owner/"); - let compiled_modules = - build_move_package_to_bytes(Path::new(&path), BuildConfig::default()).unwrap(); + let compiled_modules = BuildConfig::default() + .build(Path::new(&path).to_path_buf()) + .unwrap() + .get_package_bytes(); let data = gateway .publish( addr1, @@ -521,8 +522,10 @@ async fn test_get_owner_object() { path.push_str("/src/unit_tests/data/object_owner/"); // Publish object_owner package - let compiled_modules = - build_move_package_to_bytes(Path::new(&path), BuildConfig::default()).unwrap(); + let compiled_modules = BuildConfig::default() + .build(Path::new(&path).to_path_buf()) + .unwrap() + .get_package_bytes(); let data = gateway .publish( addr1, diff --git a/crates/sui-core/src/unit_tests/move_integration_tests.rs b/crates/sui-core/src/unit_tests/move_integration_tests.rs index 1fec2ec93f8b4..0f697f729a207 100644 --- a/crates/sui-core/src/unit_tests/move_integration_tests.rs +++ b/crates/sui-core/src/unit_tests/move_integration_tests.rs @@ -15,7 +15,7 @@ use move_core_types::{ language_storage::TypeTag, value::{MoveStruct, MoveValue}, }; -use move_package::BuildConfig; +use sui_framework_build::compiled_package::BuildConfig; use sui_types::{ crypto::{get_key_pair, AccountKeyPair}, event::{Event, EventType, TransferType}, @@ -1836,16 +1836,9 @@ pub async fn build_and_try_publish_test_package( let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("src/unit_tests/data/"); path.push(test_dir); - let modules = sui_framework::build_move_package(&path, build_config).unwrap(); - - let all_module_bytes = modules - .iter() - .map(|m| { - let mut module_bytes = Vec::new(); - m.serialize(&mut module_bytes).unwrap(); - module_bytes - }) - .collect(); + let all_module_bytes = sui_framework::build_move_package(&path, build_config) + .unwrap() + .get_package_bytes(); let gas_object = authority.get_object(gas_object_id).await.unwrap(); let gas_object_ref = gas_object.unwrap().compute_object_reference(); diff --git a/crates/sui-framework-build/Cargo.toml b/crates/sui-framework-build/Cargo.toml index 9a96a96be034b..3600d5f2e4fdd 100644 --- a/crates/sui-framework-build/Cargo.toml +++ b/crates/sui-framework-build/Cargo.toml @@ -8,7 +8,7 @@ license = "Apache-2.0" publish = false [dependencies] - +anyhow = { version = "1.0.64", features = ["backtrace"] } once_cell = "1.14.0" sui-types = { path = "../sui-types" } diff --git a/crates/sui-framework-build/src/compiled_package.rs b/crates/sui-framework-build/src/compiled_package.rs new file mode 100644 index 0000000000000..c5faa2a95442e --- /dev/null +++ b/crates/sui-framework-build/src/compiled_package.rs @@ -0,0 +1,271 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use std::{collections::HashSet, path::PathBuf}; + +use move_binary_format::CompiledModule; +use move_bytecode_utils::{module_cache::GetModule, Modules}; +use move_compiler::compiled_unit::CompiledUnitEnum; +use move_core_types::{account_address::AccountAddress, language_storage::ModuleId}; +use move_package::{ + compilation::compiled_package::CompiledPackage as MoveCompiledPackage, + BuildConfig as MoveBuildConfig, +}; +use sui_types::{ + error::{SuiError, SuiResult}, + sui_serde::Base64, + MOVE_STDLIB_ADDRESS, SUI_FRAMEWORK_ADDRESS, +}; +use sui_verifier::verifier as sui_bytecode_verifier; + +use crate::{MOVE_STDLIB_PACKAGE_NAME, SUI_PACKAGE_NAME}; + +/// Wrapper around the core Move `CompiledPackage` with some Sui-specific traits and info +pub struct CompiledPackage { + pub package: MoveCompiledPackage, + /// Path to the Move package (i.e., where the Move.toml file is) + pub path: PathBuf, +} + +/// Wrapper around the core Move `BuildConfig` with some Sui-specific info +pub struct BuildConfig { + pub config: MoveBuildConfig, + /// If true, run the Move bytecode verifier on the bytecode from a successful build + pub run_bytecode_verifier: bool, + /// If true, print build diagnostics to stderr--no printing if false + pub print_diags_to_stderr: bool, +} + +impl BuildConfig { + /// Given a `path` and a `build_config`, build the package in that path, including its dependencies. + /// If we are building the Sui framework, we skip the check that the addresses should be 0 + pub fn build(self, path: PathBuf) -> SuiResult { + let res = if self.print_diags_to_stderr { + self.config + .compile_package_no_exit(&path, &mut std::io::stderr()) + } else { + self.config.compile_package_no_exit(&path, &mut Vec::new()) + }; + + // write build failure diagnostics to stderr + let package = match res { + Err(error) => { + return Err(SuiError::ModuleBuildFailure { + error: error.to_string(), + }) + } + Ok(package) => package, + }; + let compiled_modules = package.root_modules_map(); + let package_name = package.compiled_package_info.package_name.as_str(); + let is_framework = + package_name == SUI_PACKAGE_NAME || package_name == MOVE_STDLIB_PACKAGE_NAME; + if !is_framework { + if let Some(m) = compiled_modules + .iter_modules() + .iter() + .find(|m| m.self_id().address() != &AccountAddress::ZERO) + { + // TODO: this should be a generic build failure, not a Sui module publish failure + return Err(SuiError::ModulePublishFailure { + error: format!( + "Modules must all have 0x0 as their addresses. Violated by module {:?}", + m.self_id() + ), + }); + } + } + if self.run_bytecode_verifier { + for m in compiled_modules.iter_modules() { + move_bytecode_verifier::verify_module(m).map_err(|err| { + SuiError::ModuleVerificationFailure { + error: err.to_string(), + } + })?; + sui_bytecode_verifier::verify_module(m)?; + } + // TODO(https://github.com/MystenLabs/sui/issues/69): Run Move linker + } + Ok(CompiledPackage { package, path }) + } +} + +impl CompiledPackage { + /// Return all of the bytecode modules in this package (not including direct or transitive deps) + /// Note: these are not topologically sorted by dependency--use `get_dependency_sorted_modules` to produce a list of modules suitable + /// for publishing or static analysis + pub fn get_modules(&self) -> impl Iterator { + self.package.root_modules().map(|m| match &m.unit { + CompiledUnitEnum::Module(m) => &m.module, + CompiledUnitEnum::Script(_) => unimplemented!("Scripts not supported in Sui Move"), + }) + } + + /// Return all of the bytecode modules in this package (not including direct or transitive deps) + /// Note: these are not topologically sorted by dependency--use `get_dependency_sorted_modules` to produce a list of modules suitable + /// for publishing or static analysis + pub fn into_modules(self) -> Vec { + self.package + .root_compiled_units + .into_iter() + .map(|m| match m.unit { + CompiledUnitEnum::Module(m) => m.module, + CompiledUnitEnum::Script(_) => unimplemented!("Scripts not supported in Sui Move"), + }) + .collect() + } + + /// Return all of the bytecode modules that this package depends on (both directly and transitively) + /// Note: these are not topologically sorted by dependency. + pub fn get_dependent_modules(&self) -> impl Iterator { + self.package + .deps_compiled_units + .iter() + .map(|(_, m)| match &m.unit { + CompiledUnitEnum::Module(m) => &m.module, + CompiledUnitEnum::Script(_) => unimplemented!("Scripts not supported in Sui Move"), + }) + } + + /// Return all of the bytecode modules in this package and the modules of its direct and transitive dependencies. + /// Note: these are not topologically sorted by dependency. + pub fn get_modules_and_deps(&self) -> impl Iterator { + self.package.all_modules().map(|m| match &m.unit { + CompiledUnitEnum::Module(m) => &m.module, + CompiledUnitEnum::Script(_) => unimplemented!("Scripts not supported in Sui Move"), + }) + } + + /// Return the bytecode modules in this package, topologically sorted in dependency order + /// This is the function to call if you would like to publish or statically analyze the modules + pub fn get_dependency_sorted_modules(&self) -> Vec { + let compiled_modules = self.package.root_modules_map(); + // Collect all module IDs from the current package to be + // published (module names are not sufficient as we may + // have modules with the same names in user code and in + // Sui framework which would result in the latter being + // pulled into a set of modules to be published). + // For each transitive dependent module, if they are not to be published, + // they must have a non-zero address (meaning they are already published on-chain). + let self_modules: HashSet = compiled_modules + .iter_modules() + .iter() + .map(|m| m.self_id()) + .collect(); + self.package + .all_modules_map() + .compute_dependency_graph() + .compute_topological_order() + .unwrap() // safe because package built successfully + .filter(|m| self_modules.contains(&m.self_id())) + .cloned() + .collect() + } + + /// Return a serialized representation of the bytecode modules in this package, topologically sorted in dependency order + pub fn get_package_bytes(&self) -> Vec> { + self.get_dependency_sorted_modules() + .iter() + .map(|m| { + let mut bytes = Vec::new(); + m.serialize(&mut bytes).unwrap(); // safe because package built successfully + bytes + }) + .collect() + } + + /// Return the base64-encoded representation of the bytecode modules in this package, topologically sorted in dependency order + pub fn get_package_base64(&self) -> Vec { + self.get_package_bytes() + .iter() + .map(|b| Base64::from_bytes(b)) + .collect() + } + + /// Get bytecode modules from the Sui Framework that are used by this package + pub fn get_framework_modules(&self) -> impl Iterator { + self.get_modules_and_deps() + .filter(|m| *m.self_id().address() == SUI_FRAMEWORK_ADDRESS) + } + + /// Get bytecode modules from the Move stdlib that are used by this package + pub fn get_stdlib_modules(&self) -> impl Iterator { + self.get_modules_and_deps() + .filter(|m| *m.self_id().address() == MOVE_STDLIB_ADDRESS) + } + + /// Version of the framework code that the binary used for compilation expects should be the same as + /// version of the framework code bundled as compiled package's dependency and this function + /// verifies this. + // TODO: replace this with actual versioning checks instead of hacky byte-for-byte comparisons + pub fn verify_framework_version( + &self, + ext_sui_framework: Vec, + ext_move_stdlib: Vec, + ) -> SuiResult<()> { + // We stash compiled modules in the Modules map which is sorted so that we can compare sets of + // compiled modules directly. + let ext_framework_modules = Modules::new(ext_sui_framework.iter()); + let pkg_framework_modules: Vec<&CompiledModule> = self.get_framework_modules().collect(); + + // compare framework modules pulled as dependencies (if any - a developer may choose to use only + // stdlib) with framework modules bundled with the distribution + if !pkg_framework_modules.is_empty() + && ext_framework_modules != Modules::new(pkg_framework_modules) + { + // note: this advice is overfitted to the most common failure modes we see: + // user is trying to publish to testnet, but has a `sui` binary and Sui Framework + // sources that are not in sync. the first part of the advice ensures that the + // user's project is always pointing at the devnet copy of the `Sui` Framework. + // the second ensures that the `sui` binary matches the devnet framework + return Err(SuiError::ModuleVerificationFailure { + error: "Sui framework version mismatch detected.\ + Make sure that you are using a GitHub dep in your Move.toml:\ + \ + [dependencies] + Sui = { git = \"https://github.com/MystenLabs/sui.git\", subdir = \"crates/sui-framework\", rev = \"devnet\" } +` \ + If that does not fix the issue, your `sui` binary is likely out of date--try \ + cargo install --locked --git https://github.com/MystenLabs/sui.git --branch devnet sui" + .to_string(), + }); + } + + let ext_stdlib_modules = Modules::new(ext_move_stdlib.iter()); + let pkg_stdlib_modules: Vec<&CompiledModule> = self.get_stdlib_modules().collect(); + + // compare stdlib modules pulled as dependencies (if any) with stdlib modules bundled with the + // distribution + if !pkg_stdlib_modules.is_empty() && ext_stdlib_modules != Modules::new(pkg_stdlib_modules) + { + return Err(SuiError::ModuleVerificationFailure { + error: "Move stdlib version mismatch detected.\ + Make sure that the sui command line tool and the Move standard library code\ + used as a dependency correspond to the same git commit" + .to_string(), + }); + } + + Ok(()) + } +} + +impl Default for BuildConfig { + fn default() -> Self { + BuildConfig { + config: MoveBuildConfig::default(), + run_bytecode_verifier: true, + print_diags_to_stderr: false, + } + } +} + +impl GetModule for CompiledPackage { + type Error = anyhow::Error; + // TODO: return ref here for better efficiency? Borrow checker + all_modules_map() make it hard to do this + type Item = CompiledModule; + + fn get_module_by_id(&self, id: &ModuleId) -> Result, Self::Error> { + Ok(self.package.all_modules_map().get_module(id).ok().cloned()) + } +} diff --git a/crates/sui-framework-build/src/lib.rs b/crates/sui-framework-build/src/lib.rs index e7b71c3eec609..849b66ce80863 100644 --- a/crates/sui-framework-build/src/lib.rs +++ b/crates/sui-framework-build/src/lib.rs @@ -1,110 +1,7 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -use move_binary_format::CompiledModule; -use move_compiler::compiled_unit::{CompiledUnit, NamedCompiledModule}; -use move_core_types::{account_address::AccountAddress, language_storage::ModuleId}; -use move_package::{compilation::compiled_package::CompiledPackage, BuildConfig}; -use std::{collections::HashSet, path::Path}; -use sui_types::error::{SuiError, SuiResult}; -use sui_verifier::verifier as sui_bytecode_verifier; +pub mod compiled_package; const SUI_PACKAGE_NAME: &str = "Sui"; const MOVE_STDLIB_PACKAGE_NAME: &str = "MoveStdlib"; - -pub fn build_move_stdlib_modules(lib_dir: &Path) -> SuiResult> { - let build_config = BuildConfig::default(); - let pkg = build_move_package_with_deps(lib_dir, build_config)?; - let modules: Vec = filter_package_modules(&pkg)?; - verify_modules(&modules)?; - Ok(modules) -} - -pub fn verify_modules(modules: &[CompiledModule]) -> SuiResult { - for m in modules { - move_bytecode_verifier::verify_module(m).map_err(|err| { - SuiError::ModuleVerificationFailure { - error: err.to_string(), - } - })?; - sui_bytecode_verifier::verify_module(m)?; - } - Ok(()) - // TODO(https://github.com/MystenLabs/sui/issues/69): Run Move linker -} - -/// Given a `path` and a `build_config`, build the package in that path, including its dependencies. -/// If we are building the Sui framework, we skip the check that the addresses should be 0 -pub fn build_move_package_with_deps( - path: &Path, - build_config: BuildConfig, -) -> SuiResult { - match build_config.compile_package_no_exit(path, &mut Vec::new()) { - Err(error) => Err(SuiError::ModuleBuildFailure { - error: error.to_string(), - }), - Ok(package) => { - let compiled_modules = package.root_modules_map(); - let package_name = package.compiled_package_info.package_name.as_str(); - let is_framework = - package_name == SUI_PACKAGE_NAME || package_name == MOVE_STDLIB_PACKAGE_NAME; - if !is_framework { - if let Some(m) = compiled_modules - .iter_modules() - .iter() - .find(|m| m.self_id().address() != &AccountAddress::ZERO) - { - return Err(SuiError::ModulePublishFailure { - error: format!( - "Modules must all have 0x0 as their addresses. Violated by module {:?}", - m.self_id() - ), - }); - } - } - Ok(package) - } - } -} - -/// Given a package bundled with its dependencies, filter out modules that only belong to this -/// package. -pub fn filter_package_modules(package: &CompiledPackage) -> SuiResult> { - let compiled_modules = package.root_modules_map(); - // Collect all module IDs from the current package to be - // published (module names are not sufficient as we may - // have modules with the same names in user code and in - // Sui framework which would result in the latter being - // pulled into a set of modules to be published). - // For each transitive dependent module, if they are not to be published, - // they must have a non-zero address (meaning they are already published on-chain). - // TODO: Shall we also check if they are really on-chain in the future? - let self_modules: HashSet = compiled_modules - .iter_modules() - .iter() - .map(|m| m.self_id()) - .collect(); - if let Some(m) = package - .deps_compiled_units - .iter() - .find_map(|(_, unit)| match &unit.unit { - CompiledUnit::Module(NamedCompiledModule { module: m, .. }) - if !self_modules.contains(&m.self_id()) - && m.self_id().address() == &AccountAddress::ZERO => - { - Some(m) - } - _ => None, - }) - { - return Err(SuiError::ModulePublishFailure { error: format!("Dependent modules must have been published on-chain with non-0 addresses, unlike module {:?}", m.self_id()) }); - } - Ok(package - .all_modules_map() - .compute_dependency_graph() - .compute_topological_order() - .unwrap() - .filter(|m| self_modules.contains(&m.self_id())) - .cloned() - .collect()) -} diff --git a/crates/sui-framework/Cargo.toml b/crates/sui-framework/Cargo.toml index b2af650b7cc45..2226484b3cba7 100644 --- a/crates/sui-framework/Cargo.toml +++ b/crates/sui-framework/Cargo.toml @@ -17,16 +17,15 @@ num_enum = "0.5.7" once_cell = "1.14.0" sha3 = "0.10.4" curve25519-dalek-ng = "4.1.1" + fastcrypto.workspace = true digest = "0.10.3" serde = { version = "1.0.144", features = ["derive"] } -sui-types = { path = "../sui-types" } sui-framework-build = { path = "../sui-framework-build" } -sui-verifier = { path = "../../crates/sui-verifier" } +sui-types = { path = "../sui-types" } move-binary-format.workspace = true -move-bytecode-utils.workspace = true move-bytecode-verifier.workspace = true move-cli.workspace = true move-compiler.workspace = true @@ -43,7 +42,9 @@ workspace-hack.workspace = true [build-dependencies] anyhow = { version = "1.0.64", features = ["backtrace"] } bcs = "0.1.4" + sui-framework-build = { path = "../sui-framework-build" } + move-binary-format.workspace = true move-package.workspace = true diff --git a/crates/sui-framework/build.rs b/crates/sui-framework/build.rs index 65e68e3df12ea..8edd9dc34b3b9 100644 --- a/crates/sui-framework/build.rs +++ b/crates/sui-framework/build.rs @@ -3,13 +3,15 @@ use anyhow::Result; use move_binary_format::CompiledModule; -use move_package::BuildConfig; +use move_package::BuildConfig as MoveBuildConfig; use std::thread::Builder; use std::{ env, fs, path::{Path, PathBuf}, }; +use sui_framework_build::compiled_package::BuildConfig; + const FRAMEWORK_DOCS_DIR: &str = "docs"; /// Save revision info to environment variable @@ -19,17 +21,13 @@ fn main() { let sui_framework_path = Path::new(env!("CARGO_MANIFEST_DIR")); let move_stdlib_path = sui_framework_path.join("deps").join("move-stdlib"); - let stdlib_path = move_stdlib_path.clone(); - let (sui_framework, move_stdlib) = Builder::new() + Builder::new() .stack_size(16 * 1024 * 1024) // build_move_package require bigger stack size on windows. - .spawn(move || build_framework_and_stdlib(sui_framework_path, &stdlib_path)) + .spawn(move || build_framework_and_stdlib(sui_framework_path, out_dir)) .unwrap() .join() .unwrap(); - serialize_modules_to_file(sui_framework, &out_dir.join("sui-framework")).unwrap(); - serialize_modules_to_file(move_stdlib, &out_dir.join("move-stdlib")).unwrap(); - println!("cargo:rerun-if-changed=build.rs"); println!( "cargo:rerun-if-changed={}", @@ -49,38 +47,46 @@ fn main() { ); } -fn build_framework_and_stdlib( - sui_framework_path: &Path, - move_stdlib_path: &Path, -) -> (Vec, Vec) { - let config = BuildConfig { +fn build_framework_and_stdlib(sui_framework_path: &Path, out_dir: PathBuf) { + let config = MoveBuildConfig { generate_docs: true, ..Default::default() }; - let pkg = - sui_framework_build::build_move_package_with_deps(sui_framework_path, config).unwrap(); - let sui_framework = sui_framework_build::filter_package_modules(&pkg).unwrap(); - let move_stdlib = sui_framework_build::build_move_stdlib_modules(move_stdlib_path).unwrap(); - // copy generated docs from build/Sui/docs to docs/ - for (fname, _) in pkg.compiled_docs.unwrap() { - let mut src_path = PathBuf::from("build"); - src_path.push("Sui"); - src_path.push("docs"); - src_path.push(fname.clone()); + let pkg = BuildConfig { + config, + run_bytecode_verifier: true, + print_diags_to_stderr: false, + } + .build(sui_framework_path.to_path_buf()) + .unwrap(); + let sui_framework = pkg.get_framework_modules(); + let move_stdlib = pkg.get_stdlib_modules(); + + serialize_modules_to_file(sui_framework, &out_dir.join("sui-framework")).unwrap(); + serialize_modules_to_file(move_stdlib, &out_dir.join("move-stdlib")).unwrap(); + // write out generated docs + // TODO: remove docs of deleted files + for (fname, doc) in pkg.package.compiled_docs.unwrap() { let mut dst_path = PathBuf::from(FRAMEWORK_DOCS_DIR); dst_path.push(fname); - fs::copy(src_path, dst_path).unwrap(); + fs::write(dst_path, doc).unwrap(); } - (sui_framework, move_stdlib) } -fn serialize_modules_to_file(modules: Vec, file: &Path) -> Result<()> { +fn serialize_modules_to_file<'a>( + modules: impl Iterator, + file: &Path, +) -> Result<()> { let mut serialized_modules = Vec::new(); for module in modules { let mut buf = Vec::new(); module.serialize(&mut buf)?; serialized_modules.push(buf); } + assert!( + !serialized_modules.is_empty(), + "Failed to find framework or stdlib modules" + ); let binary = bcs::to_bytes(&serialized_modules)?; diff --git a/crates/sui-framework/src/lib.rs b/crates/sui-framework/src/lib.rs index 8ec66e6f0fbec..27a9e0b31a541 100644 --- a/crates/sui-framework/src/lib.rs +++ b/crates/sui-framework/src/lib.rs @@ -2,32 +2,24 @@ // SPDX-License-Identifier: Apache-2.0 use move_binary_format::CompiledModule; -use move_bytecode_utils::Modules; use move_cli::base::test::UnitTestResult; use move_core_types::gas_algebra::InternalGas; -use move_package::{compilation::compiled_package::CompiledPackage, BuildConfig}; +use move_package::BuildConfig as MoveBuildConfig; use move_unit_test::{extensions::set_extension_hook, UnitTestingConfig}; use move_vm_runtime::native_extensions::NativeContextExtensions; use natives::object_runtime::ObjectRuntime; use once_cell::sync::Lazy; use std::{collections::BTreeMap, path::Path}; +use sui_framework_build::compiled_package::{BuildConfig, CompiledPackage}; use sui_types::{ - base_types::TransactionDigest, - error::{SuiError, SuiResult}, - in_memory_storage::InMemoryStorage, - messages::InputObjects, - temporary_store::TemporaryStore, - MOVE_STDLIB_ADDRESS, SUI_FRAMEWORK_ADDRESS, + base_types::TransactionDigest, error::SuiResult, in_memory_storage::InMemoryStorage, + messages::InputObjects, temporary_store::TemporaryStore, MOVE_STDLIB_ADDRESS, + SUI_FRAMEWORK_ADDRESS, }; pub mod cost_calib; pub mod natives; -pub use sui_framework_build::build_move_stdlib_modules as get_move_stdlib_modules; -pub use sui_framework_build::verify_modules; -use sui_framework_build::{build_move_package_with_deps, filter_package_modules}; -use sui_types::sui_serde::{Base64, Encoding}; - // Move unit tests will halt after executing this many steps. This is a protection to avoid divergence const MAX_UNIT_TEST_INSTRUCTIONS: u64 = 100_000; @@ -97,47 +89,11 @@ pub fn legacy_length_cost() -> InternalGas { InternalGas::new(98) } -/// Given a `path` and a `build_config`, build the package in that path and return the compiled modules as base64. -/// This is useful for when publishing via JSON -pub fn build_move_package_to_base64( - path: &Path, - build_config: BuildConfig, -) -> Result, SuiError> { - build_move_package_to_bytes(path, build_config) - .map(|mods| mods.iter().map(Base64::encode).collect::>()) -} - -/// Given a `path` and a `build_config`, build the package in that path and return the compiled modules as Vec>. -/// This is useful for when publishing -pub fn build_move_package_to_bytes( - path: &Path, - build_config: BuildConfig, -) -> Result>, SuiError> { - build_move_package(path, build_config).map(|mods| { - mods.iter() - .map(|m| { - let mut bytes = Vec::new(); - m.serialize(&mut bytes).unwrap(); - bytes - }) - .collect::>() - }) -} - -pub fn build_and_verify_package( - path: &Path, - build_config: BuildConfig, -) -> SuiResult> { - let modules = build_move_package(path, build_config)?; - verify_modules(&modules)?; - Ok(modules) -} - /// This function returns a result of UnitTestResult. The outer result indicates whether it /// successfully started running the test, and the inner result indicatests whether all tests pass. pub fn run_move_unit_tests( path: &Path, - build_config: BuildConfig, + build_config: MoveBuildConfig, config: Option, compute_coverage: bool, ) -> anyhow::Result { @@ -160,73 +116,12 @@ pub fn run_move_unit_tests( ) } -pub fn build_move_package( - path: &Path, - build_config: BuildConfig, -) -> SuiResult> { - let pkg = build_move_package_with_deps(path, build_config)?; - verify_framework_version(&pkg)?; - filter_package_modules(&pkg) -} - -/// Version of the framework code that the binary used for compilation expects should be the same as -/// version of the framework code bundled as compiled package's dependency and this function -/// verifies this. -fn verify_framework_version(pkg: &CompiledPackage) -> SuiResult<()> { - // We stash compiled modules in the Modules map which is sorted so that we can compare sets of - // compiled modules directly. - - let dep_framework_modules = pkg.all_modules_map().iter_modules_owned(); - let dep_framework: Vec<&CompiledModule> = dep_framework_modules - .iter() - .filter(|m| *m.self_id().address() == SUI_FRAMEWORK_ADDRESS) - .collect(); - - let framework_modules = Modules::new(get_sui_framework().iter()).iter_modules_owned(); - let framework: Vec<&CompiledModule> = framework_modules.iter().collect(); - - // compare framework modules pulled as dependencies (if any - a developer may choose to use only - // stdlib) with framework modules bundled with the distribution - if !dep_framework.is_empty() && dep_framework != framework { - // note: this advice is overfitted to the most common failure modes we see: - // user is trying to publish to testnet, but has a `sui` binary and Sui Framework - // sources that are not in sync. the first part of the advice ensures that the - // user's project is always pointing at the devnet copy of the `Sui` Framework. - // the second ensures that the `sui` binary matches the devnet framework - return Err(SuiError::ModuleVerificationFailure { - error: "Sui framework version mismatch detected.\ - Make sure that you are using a GitHub dep in your Move.toml:\ - \ - [dependencies] - Sui = { git = \"https://github.com/MystenLabs/sui.git\", subdir = \"crates/sui-framework\", rev = \"devnet\" } -` \ - If that does not fix the issue, your `sui` binary is likely out of date--try \ - cargo install --locked --git https://github.com/MystenLabs/sui.git --branch devnet sui" - .to_string(), - }); - } - - let dep_stdlib_modules = pkg.all_modules_map().iter_modules_owned(); - let dep_stdlib: Vec<&CompiledModule> = dep_stdlib_modules - .iter() - .filter(|m| *m.self_id().address() == MOVE_STDLIB_ADDRESS) - .collect(); - - let stdlib_modules = Modules::new(get_move_stdlib().iter()).iter_modules_owned(); - let stdlib: Vec<&CompiledModule> = stdlib_modules.iter().collect(); - - // compare stdlib modules pulled as dependencies (if any) with stdlib modules bundled with the - // distribution - if !dep_stdlib.is_empty() && dep_stdlib != stdlib { - return Err(SuiError::ModuleVerificationFailure { - error: "Move stdlib version mismatch detected.\ - Make sure that the sui command line tool and the Move standard library code\ - used as a dependency correspond to the same git commit" - .to_string(), - }); - } - - Ok(()) +/// Wrapper of the build command that verifies the framework version. Should eventually be removed once we can +/// do this in the obvious way (via version checks) +pub fn build_move_package(path: &Path, config: BuildConfig) -> SuiResult { + let pkg = config.build(path.to_path_buf())?; + pkg.verify_framework_version(get_sui_framework(), get_move_stdlib())?; + Ok(pkg) } #[cfg(test)] @@ -240,7 +135,7 @@ mod tests { get_sui_framework(); get_move_stdlib(); let path = PathBuf::from(DEFAULT_FRAMEWORK_PATH); - build_and_verify_package(&path, BuildConfig::default()).unwrap(); + BuildConfig::default().build(path.clone()).unwrap(); check_move_unit_tests(&path); } @@ -260,7 +155,7 @@ mod tests { let path = Path::new(env!("CARGO_MANIFEST_DIR")) .join("../../sui_programmability/examples") .join(example); - build_and_verify_package(&path, BuildConfig::default()).unwrap(); + BuildConfig::default().build(path.clone()).unwrap(); check_move_unit_tests(&path); } } @@ -270,13 +165,13 @@ mod tests { fn run_book_examples_move_unit_tests() { let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../doc/book/examples"); - build_and_verify_package(&path, BuildConfig::default()).unwrap(); + BuildConfig::default().build(path.clone()).unwrap(); check_move_unit_tests(&path); } fn check_move_unit_tests(path: &Path) { assert_eq!( - run_move_unit_tests(path, BuildConfig::default(), None, false).unwrap(), + run_move_unit_tests(path, MoveBuildConfig::default(), None, false).unwrap(), UnitTestResult::Success ); } diff --git a/crates/sui-gateway/Cargo.toml b/crates/sui-gateway/Cargo.toml index d1b8a9bbc7f8b..14615d709a524 100644 --- a/crates/sui-gateway/Cargo.toml +++ b/crates/sui-gateway/Cargo.toml @@ -28,12 +28,11 @@ sui-keys = { path = "../sui-keys" } mysten-network.workspace = true -move-package.workspace = true workspace-hack.workspace = true [dev-dependencies] test-utils = { path = "../test-utils" } -sui-framework = { path = "../sui-framework" } +sui-framework-build = { path = "../sui-framework-build" } sui-sdk = { path = "../sui-sdk" } [[bin]] diff --git a/crates/sui-gateway/src/unit_tests/rpc_server_tests.rs b/crates/sui-gateway/src/unit_tests/rpc_server_tests.rs index 600a4d8c66789..b4dc87686a9a0 100644 --- a/crates/sui-gateway/src/unit_tests/rpc_server_tests.rs +++ b/crates/sui-gateway/src/unit_tests/rpc_server_tests.rs @@ -4,12 +4,10 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::{path::Path, str::FromStr}; -use move_package::BuildConfig; - use sui_config::utils::get_available_port; use sui_config::SUI_KEYSTORE_FILENAME; use sui_core::test_utils::to_sender_signed_transaction; -use sui_framework::build_move_package_to_bytes; +use sui_framework_build::compiled_package::BuildConfig; use sui_json::SuiJsonValue; use sui_json_rpc::api::{ RpcGatewayApiClient, RpcReadApiClient, RpcTransactionBuilderClient, WalletSyncApiClient, @@ -22,7 +20,6 @@ use sui_types::base_types::TransactionDigest; use sui_types::gas_coin::GAS; use sui_types::messages::ExecuteTransactionRequestType; use sui_types::query::{Ordering, TransactionQuery}; -use sui_types::sui_serde::Base64; use sui_types::SUI_FRAMEWORK_ADDRESS; use test_utils::network::TestClusterBuilder; @@ -93,13 +90,9 @@ async fn test_publish() -> Result<(), anyhow::Error> { let objects = http_client.get_objects_owned_by_address(*address).await?; let gas = objects.first().unwrap(); - let compiled_modules = build_move_package_to_bytes( - Path::new("../../sui_programmability/examples/fungible_tokens"), - BuildConfig::default(), - )? - .iter() - .map(|bytes| Base64::from_bytes(bytes)) - .collect::>(); + let compiled_modules = BuildConfig::default() + .build(Path::new("../../sui_programmability/examples/fungible_tokens").to_path_buf())? + .get_package_base64(); let transaction_bytes: TransactionBytes = http_client .publish(*address, compiled_modules, Some(gas.object_id), 10000) diff --git a/crates/sui-json/Cargo.toml b/crates/sui-json/Cargo.toml index 4e85fc99c9545..1e4fd41b7c05a 100644 --- a/crates/sui-json/Cargo.toml +++ b/crates/sui-json/Cargo.toml @@ -22,8 +22,7 @@ move-core-types.workspace = true [dev-dependencies] test-fuzz = "3.0.4" -move-package.workspace = true workspace-hack.workspace = true sui-adapter = { path = "../sui-adapter" } -sui-framework = { path = "../sui-framework" } +sui-framework-build = { path = "../sui-framework-build" } diff --git a/crates/sui-json/src/tests.rs b/crates/sui-json/src/tests.rs index 8cd7686a2c0ae..6348f7150883d 100644 --- a/crates/sui-json/src/tests.rs +++ b/crates/sui-json/src/tests.rs @@ -8,6 +8,7 @@ use move_core_types::{ account_address::AccountAddress, identifier::Identifier, value::MoveTypeLayout, }; use serde_json::{json, Value}; +use sui_framework_build::compiled_package::BuildConfig; use test_fuzz::runtime::num_traits::ToPrimitive; use sui_types::base_types::{ObjectID, SuiAddress, TransactionDigest}; @@ -290,9 +291,7 @@ fn test_basic_args_linter_pure_args() { fn test_basic_args_linter_top_level() { let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../sui_programmability/examples/nfts"); - let compiled_modules = - sui_framework::build_and_verify_package(&path, move_package::BuildConfig::default()) - .unwrap(); + let compiled_modules = BuildConfig::default().build(path).unwrap().into_modules(); let example_package = Object::new_package(compiled_modules, TransactionDigest::genesis()); let example_package = example_package.data.try_as_package().unwrap(); @@ -394,9 +393,7 @@ fn test_basic_args_linter_top_level() { // Test with vecu8 as address let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../sui_programmability/examples/basics"); - let compiled_modules = - sui_framework::build_and_verify_package(&path, move_package::BuildConfig::default()) - .unwrap(); + let compiled_modules = BuildConfig::default().build(path).unwrap().into_modules(); let example_package = Object::new_package(compiled_modules, TransactionDigest::genesis()); let framework_pkg = example_package.data.try_as_package().unwrap(); @@ -475,9 +472,7 @@ fn test_basic_args_linter_top_level() { // Test with object vector args let path = Path::new(env!("CARGO_MANIFEST_DIR")) .join("../sui-core/src/unit_tests/data/entry_point_vector"); - let compiled_modules = - sui_framework::build_and_verify_package(&path, move_package::BuildConfig::default()) - .unwrap(); + let compiled_modules = BuildConfig::default().build(path).unwrap().into_modules(); let example_package = Object::new_package(compiled_modules, TransactionDigest::genesis()); let example_package = example_package.data.try_as_package().unwrap(); diff --git a/crates/sui/Cargo.toml b/crates/sui/Cargo.toml index ec0dde4411ecd..c7c37b9949c44 100644 --- a/crates/sui/Cargo.toml +++ b/crates/sui/Cargo.toml @@ -23,6 +23,7 @@ bip32 = "0.4.0" sui-core = { path = "../sui-core" } sui-framework = { path = "../sui-framework" } +sui-framework-build = { path = "../sui-framework-build" } sui-config = { path = "../sui-config" } sui-types = { path = "../sui-types" } sui-json = { path = "../sui-json" } diff --git a/crates/sui/src/client_commands.rs b/crates/sui/src/client_commands.rs index f371b5356f977..a074a20245668 100644 --- a/crates/sui/src/client_commands.rs +++ b/crates/sui/src/client_commands.rs @@ -15,13 +15,14 @@ use clap::*; use colored::Colorize; use fastcrypto::traits::ToFromBytes; use move_core_types::language_storage::TypeTag; -use move_package::BuildConfig; +use move_package::BuildConfig as MoveBuildConfig; use serde::Serialize; use serde_json::json; use tracing::info; use crate::config::{Config, PersistedConfig, SuiClientConfig}; -use sui_framework::build_move_package_to_bytes; +use sui_framework::build_move_package; +use sui_framework_build::compiled_package::BuildConfig; use sui_json::SuiJsonValue; use sui_json_rpc_types::{ GetObjectDataResponse, SuiObjectInfo, SuiParsedObject, SuiTransactionResponse, @@ -98,7 +99,7 @@ pub enum SuiClientCommands { /// Package build options #[clap(flatten)] - build_config: BuildConfig, + build_config: MoveBuildConfig, /// ID of the gas object for gas payment, in 20 bytes Hex string /// If not provided, a gas object with at least gas_budget value will be selected @@ -403,7 +404,15 @@ impl SuiClientCommands { let sender = context.try_get_object_owner(&gas).await?; let sender = sender.unwrap_or(context.active_address()?); - let compiled_modules = build_move_package_to_bytes(&package_path, build_config)?; + let compiled_modules = build_move_package( + &package_path, + BuildConfig { + config: build_config, + run_bytecode_verifier: true, + print_diags_to_stderr: true, + }, + )? + .get_package_bytes(); let data = context .client .transaction_builder() diff --git a/crates/sui/src/sui_move/build.rs b/crates/sui/src/sui_move/build.rs index ee3015321e6f6..f9f478947d2d1 100644 --- a/crates/sui/src/sui_move/build.rs +++ b/crates/sui/src/sui_move/build.rs @@ -3,8 +3,9 @@ use clap::Parser; use move_cli::base::{self, build}; -use move_package::BuildConfig; +use move_package::BuildConfig as MoveBuildConfig; use std::path::{Path, PathBuf}; +use sui_framework_build::compiled_package::BuildConfig; #[derive(Parser)] pub struct Build { @@ -16,22 +17,30 @@ pub struct Build { } impl Build { - pub fn execute(&self, path: Option, build_config: BuildConfig) -> anyhow::Result<()> { + pub fn execute( + &self, + path: Option, + build_config: MoveBuildConfig, + ) -> anyhow::Result<()> { let rerooted_path = base::reroot_path(path)?; Self::execute_internal(&rerooted_path, build_config, self.dump_bytecode_as_base64) } + pub fn execute_internal( rerooted_path: &Path, - build_config: BuildConfig, + config: MoveBuildConfig, dump_bytecode_as_base64: bool, ) -> anyhow::Result<()> { - // find manifest file directory from a given path or (if missing) from current dir + let pkg = sui_framework::build_move_package( + rerooted_path, + BuildConfig { + config, + run_bytecode_verifier: false, + print_diags_to_stderr: true, + }, + )?; if dump_bytecode_as_base64 { - let compiled_modules = - sui_framework::build_move_package_to_base64(rerooted_path, build_config)?; - println!("{:?}", compiled_modules); - } else { - sui_framework::build_and_verify_package(rerooted_path, build_config)?; + println!("{:?}", pkg.get_package_base64()) } Ok(()) } diff --git a/crates/test-utils/Cargo.toml b/crates/test-utils/Cargo.toml index 297947ca7a100..735fe95f1ca18 100644 --- a/crates/test-utils/Cargo.toml +++ b/crates/test-utils/Cargo.toml @@ -24,6 +24,7 @@ sui-adapter = { path = "../sui-adapter" } sui-config = { path = "../sui-config" } sui-core = { path = "../sui-core" } sui-framework = { path = "../sui-framework" } +sui-framework-build = { path = "../sui-framework-build" } sui-json-rpc = { path = "../sui-json-rpc" } sui-json-rpc-types= { path = "../sui-json-rpc-types" } sui-node = { path = "../sui-node" } @@ -35,7 +36,6 @@ once_cell = "1.14.0" multiaddr = "0.14.0" mysten-network.workspace = true -move-package.workspace = true move-core-types.workspace = true workspace-hack.workspace = true diff --git a/crates/test-utils/src/messages.rs b/crates/test-utils/src/messages.rs index af860482e7e14..6adbdbdaffc9f 100644 --- a/crates/test-utils/src/messages.rs +++ b/crates/test-utils/src/messages.rs @@ -6,12 +6,12 @@ use crate::{test_account_keys, test_committee, test_validator_keys}; use move_core_types::account_address::AccountAddress; use move_core_types::ident_str; use move_core_types::language_storage::TypeTag; -use move_package::BuildConfig; use std::path::PathBuf; use sui::client_commands::WalletContext; use sui::client_commands::{SuiClientCommandResult, SuiClientCommands}; use sui_adapter::genesis; use sui_core::test_utils::to_sender_signed_transaction; +use sui_framework_build::compiled_package::BuildConfig; use sui_json_rpc_types::SuiObjectInfo; use sui_keys::keystore::AccountKeystore; use sui_keys::keystore::Keystore; @@ -273,16 +273,9 @@ pub fn create_publish_move_package_transaction( keypair: &AccountKeyPair, ) -> VerifiedTransaction { let build_config = BuildConfig::default(); - let modules = sui_framework::build_move_package(&path, build_config).unwrap(); - - let all_module_bytes = modules - .iter() - .map(|m| { - let mut module_bytes = Vec::new(); - m.serialize(&mut module_bytes).unwrap(); - module_bytes - }) - .collect(); + let all_module_bytes = sui_framework::build_move_package(&path, build_config) + .unwrap() + .get_package_bytes(); let data = TransactionData::new_module(sender, gas_object_ref, all_module_bytes, MAX_GAS); to_sender_signed_transaction(data, keypair) } @@ -325,15 +318,9 @@ pub fn make_publish_basics_transaction(gas_object: ObjectRef) -> VerifiedTransac let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("../../sui_programmability/examples/basics"); let build_config = BuildConfig::default(); - let modules = sui_framework::build_move_package(&path, build_config).unwrap(); - let all_module_bytes = modules - .iter() - .map(|m| { - let mut module_bytes = Vec::new(); - m.serialize(&mut module_bytes).unwrap(); - module_bytes - }) - .collect(); + let all_module_bytes = sui_framework::build_move_package(&path, build_config) + .unwrap() + .get_package_bytes(); let data = TransactionData::new_module(sender, gas_object, all_module_bytes, MAX_GAS); to_sender_signed_transaction(data, &keypair) } diff --git a/crates/test-utils/src/transaction.rs b/crates/test-utils/src/transaction.rs index 5c21be8b90799..64ecbcc677d37 100644 --- a/crates/test-utils/src/transaction.rs +++ b/crates/test-utils/src/transaction.rs @@ -8,7 +8,6 @@ use crate::messages::{ }; use crate::{test_account_keys, test_committee}; use futures::StreamExt; -use move_package::BuildConfig; use serde_json::json; use std::collections::{HashMap, HashSet}; use std::path::PathBuf; @@ -18,6 +17,7 @@ use sui::client_commands::{SuiClientCommandResult, SuiClientCommands}; use sui_config::ValidatorInfo; use sui_core::authority::AuthorityState; use sui_core::authority_client::AuthorityAPI; +use sui_framework_build::compiled_package::BuildConfig; use sui_json_rpc_types::SuiCertifiedTransaction; use sui_json_rpc_types::SuiObjectRead; use sui_json_rpc_types::SuiTransactionEffects; @@ -79,16 +79,9 @@ pub fn compile_basics_package() -> Vec> { path.push("../../sui_programmability/examples/basics"); let build_config = BuildConfig::default(); - let modules = sui_framework::build_move_package(&path, build_config).unwrap(); - - modules - .iter() - .map(|m| { - let mut module_bytes = Vec::new(); - m.serialize(&mut module_bytes).unwrap(); - module_bytes - }) - .collect() + sui_framework::build_move_package(&path, build_config) + .unwrap() + .get_package_bytes() } /// Helper function to publish basic package.