Skip to content

Commit

Permalink
Merge pull request #1011 from multiversx/multicontract-fix
Browse files Browse the repository at this point in the history
Multi-contract bug fix
  • Loading branch information
andrei-marinica authored Mar 16, 2023
2 parents 6bfd309 + a900298 commit eb656dd
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 19 deletions.

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

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "multi-contract-features-wasm"
name = "multi-contract-features-custom-cargo-toml-name"
version = "0.0.0"
authors = ["Andrei Marinica <[email protected]>"]
edition = "2021"
Expand Down
11 changes: 11 additions & 0 deletions framework/meta/src/cargo_toml_contents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ impl CargoTomlContents {
.expect("failed to write Cargo.toml contents to file");
}

pub fn package_name(&self) -> String {
self.toml_value
.get("package")
.expect("missing package in Cargo.toml")
.get("name")
.expect("missing package name in Cargo.toml")
.as_str()
.expect("package name not a string value")
.to_string()
}

/// Assumes that a package section already exists.
pub fn change_package_name(&mut self, new_package_name: String) {
let package = self
Expand Down
11 changes: 7 additions & 4 deletions framework/meta/src/meta_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,16 @@ impl MetaConfig {
/// Cargo.toml files for secondary contracts are generated from the main contract Cargo.toml,
/// by changing the package name.
pub fn generate_cargo_toml_for_secondary_contracts(&mut self) {
let main_contract = self.output_contracts.main_contract();
let main_contract = self.output_contracts.main_contract_mut();

// using the same local structure for all contracts is enough for now
let mut cargo_toml_contents =
let main_cargo_toml_contents =
CargoTomlContents::load_from_file(main_contract.cargo_toml_path());
main_contract.wasm_crate_name = main_cargo_toml_contents.package_name();

// we are reusing the object, repeatedly updating and saving
let mut cargo_toml_contents = main_cargo_toml_contents;
for secondary_contract in self.output_contracts.secondary_contracts() {
cargo_toml_contents.change_package_name(secondary_contract.wasm_crate_name());
cargo_toml_contents.change_package_name(secondary_contract.wasm_crate_name.clone());
cargo_toml_contents.save_to_file(secondary_contract.cargo_toml_path());
}
}
Expand Down
12 changes: 10 additions & 2 deletions framework/meta/src/output_contract/output_contract_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,19 @@ fn build_contract_abi(builder: OutputContractBuilder, original_abi: &ContractAbi
}
}

fn default_wasm_crate_name(contract_name: &str) -> String {
format!("{contract_name}-wasm")
}

fn build_contract(builder: OutputContractBuilder, original_abi: &ContractAbi) -> OutputContract {
let name = builder.wasm_name().clone();
let contract_name = builder.wasm_name().clone();
let wasm_crate_name = default_wasm_crate_name(&contract_name);
OutputContract {
main: false,
settings: builder.settings.clone(),
contract_id: builder.contract_id.clone(),
contract_name: name,
contract_name,
wasm_crate_name,
abi: build_contract_abi(builder, original_abi),
}
}
Expand Down Expand Up @@ -249,13 +255,15 @@ impl OutputContractConfig {
/// The default configuration contains a single main contract, with all endpoints.
pub fn default_config(original_abi: &ContractAbi) -> Self {
let default_contract_config_name = original_abi.build_info.contract_crate.name.to_string();
let wasm_crate_name = default_wasm_crate_name(&default_contract_config_name);
OutputContractConfig {
default_contract_config_name: default_contract_config_name.clone(),
contracts: vec![OutputContract {
main: true,
settings: OutputContractSettings::default(),
contract_id: default_contract_config_name.clone(),
contract_name: default_contract_config_name,
wasm_crate_name,
abi: original_abi.clone(),
}],
}
Expand Down
26 changes: 18 additions & 8 deletions framework/meta/src/output_contract/output_contract_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ impl OutputContractConfig {
})
}

pub fn main_contract_mut(&mut self) -> &mut OutputContract {
self.contracts
.iter_mut()
.find(|contract| contract.main)
.unwrap_or_else(|| {
panic!(
"Could not find default contract '{}' among the output contracts.",
self.default_contract_config_name
)
})
}

pub fn secondary_contracts(&self) -> impl Iterator<Item = &OutputContract> {
self.contracts.iter().filter(move |contract| !contract.main)
}
Expand Down Expand Up @@ -82,6 +94,11 @@ pub struct OutputContract {
/// It is either defined in the multicontract.toml, or is inferred from the main crate name.
pub contract_name: String,

/// The name of the wasm crate, as it appear in Cargo.toml. It is normally the `contract_name` field, followed by the `-wasm` suffix.
///
/// However, the main contract Cargo.toml is given explicitly, so this name might differ.
pub wasm_crate_name: String,

/// Collection of flags, specified in the multicontract config.
pub settings: OutputContractSettings,

Expand Down Expand Up @@ -113,15 +130,8 @@ impl OutputContract {
format!("{}/Cargo.toml", &self.wasm_crate_path())
}

/// The name of the wasm crate, as defined in its corresponding `Cargo.toml`.
///
/// Note this does not necessarily have to match the name of the crate directory.
pub fn wasm_crate_name(&self) -> String {
format!("{}-wasm", &self.contract_name)
}

pub fn wasm_crate_name_snake_case(&self) -> String {
self.wasm_crate_name().replace('-', "_")
self.wasm_crate_name.replace('-', "_")
}

/// This is where Rust will initially compile the WASM binary.
Expand Down
7 changes: 7 additions & 0 deletions framework/meta/src/output_contract/print_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,10 @@ pub fn print_build_command(contract_name: String, command: &Command) {
format_command(command).green(),
);
}

pub fn print_copy_contract(source_wasm_path: &str, output_wasm_path: &str) {
println!(
"{}",
format!("Copying {source_wasm_path} to {output_wasm_path} ...").green(),
);
}
8 changes: 5 additions & 3 deletions framework/meta/src/output_contract/wasm_build.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::{fs, process::Command};

use super::OutputContract;
use crate::{
cli_args::BuildArgs, meta_wasm_tools, output_contract::print_util::print_build_command,
use super::{
print_util::{print_build_command, print_copy_contract},
OutputContract,
};
use crate::{cli_args::BuildArgs, meta_wasm_tools};

impl OutputContract {
pub fn build_contract(&self, build_args: &BuildArgs, output_path: &str) {
Expand Down Expand Up @@ -67,6 +68,7 @@ impl OutputContract {
fn copy_contracts_to_output(&self, build_args: &BuildArgs, output_path: &str) {
let source_wasm_path = self.wasm_compilation_output_path(&build_args.target_dir);
let output_wasm_path = format!("{output_path}/{}", self.wasm_output_name(build_args));
print_copy_contract(source_wasm_path.as_str(), output_wasm_path.as_str());
fs::copy(source_wasm_path, output_wasm_path)
.expect("failed to copy compiled contract to output directory");
}
Expand Down

0 comments on commit eb656dd

Please sign in to comment.