From bf6dc3ddf020de6daf2f23da48ebe6510905e803 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 16 Mar 2023 16:36:08 +0200 Subject: [PATCH] multi-contract conditional compilation via cargo features --- .../multi-contract-features/Cargo.toml | 3 + .../multicontract.toml | 4 + .../scenarios/mcf-example-feature.scen.json | 42 +++ ...t.scen.json => mcf-external-get.scen.json} | 0 ....scen.json => mcf-external-pure.scen.json} | 0 .../src/multi_contract_features.rs | 15 + .../tests/multi_contract_scenario_go_test.rs | 13 +- .../tests/multi_contract_scenario_rs_test.rs | 14 +- .../Cargo.lock | 262 ++++++++++++++++++ .../Cargo.toml | 25 ++ .../src/lib.rs | 26 ++ .../multi-contract-features/wasm/src/lib.rs | 5 +- framework/meta/src/cargo_toml_contents.rs | 26 ++ framework/meta/src/meta_config.rs | 25 +- .../output_contract/multi_contract_serde.rs | 3 + .../output_contract_builder.rs | 13 + .../output_contract/output_contract_model.rs | 3 + 17 files changed, 464 insertions(+), 15 deletions(-) create mode 100644 contracts/feature-tests/multi-contract-features/scenarios/mcf-example-feature.scen.json rename contracts/feature-tests/multi-contract-features/scenarios/{external-get.scen.json => mcf-external-get.scen.json} (100%) rename contracts/feature-tests/multi-contract-features/scenarios/{external-pure.scen.json => mcf-external-pure.scen.json} (100%) create mode 100644 contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.lock create mode 100644 contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.toml create mode 100644 contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/src/lib.rs diff --git a/contracts/feature-tests/multi-contract-features/Cargo.toml b/contracts/feature-tests/multi-contract-features/Cargo.toml index a42b470fe6..436f6dac24 100644 --- a/contracts/feature-tests/multi-contract-features/Cargo.toml +++ b/contracts/feature-tests/multi-contract-features/Cargo.toml @@ -8,6 +8,9 @@ publish = false [lib] path = "src/multi_contract_features.rs" +[features] +example_feature = [] + [dependencies.multiversx-sc] version = "0.39.5" path = "../../../framework/base" diff --git a/contracts/feature-tests/multi-contract-features/multicontract.toml b/contracts/feature-tests/multi-contract-features/multicontract.toml index 32aa317420..85bdb6a898 100644 --- a/contracts/feature-tests/multi-contract-features/multicontract.toml +++ b/contracts/feature-tests/multi-contract-features/multicontract.toml @@ -10,3 +10,7 @@ add-unlabelled = true # name is optional, if missing this ^^^ id will be used external-view = true add-labels = ["mcs-external-view"] + +[contracts.multi-contract-example-feature] +add-unlabelled = true +features = ["example_feature"] diff --git a/contracts/feature-tests/multi-contract-features/scenarios/mcf-example-feature.scen.json b/contracts/feature-tests/multi-contract-features/scenarios/mcf-example-feature.scen.json new file mode 100644 index 0000000000..614b40b11b --- /dev/null +++ b/contracts/feature-tests/multi-contract-features/scenarios/mcf-example-feature.scen.json @@ -0,0 +1,42 @@ +{ + "steps": [ + { + "step": "setState", + "accounts": { + "sc:mcf": { + "code": "file:../output/multi-contract-features.wasm" + }, + "sc:mcf-example-feature": { + "code": "file:../output/multi-contract-example-feature.wasm" + }, + "address:owner": {} + } + }, + { + "step": "scQuery", + "id": "example_feature_message", + "tx": { + "to": "sc:mcf-example-feature", + "function": "example_feature_message" + }, + "expect": { + "out": [ + "str:example-feature on" + ] + } + }, + { + "step": "scQuery", + "id": "example_feature_message", + "tx": { + "to": "sc:mcf", + "function": "example_feature_message" + }, + "expect": { + "out": [ + "str:example-feature off" + ] + } + } + ] +} diff --git a/contracts/feature-tests/multi-contract-features/scenarios/external-get.scen.json b/contracts/feature-tests/multi-contract-features/scenarios/mcf-external-get.scen.json similarity index 100% rename from contracts/feature-tests/multi-contract-features/scenarios/external-get.scen.json rename to contracts/feature-tests/multi-contract-features/scenarios/mcf-external-get.scen.json diff --git a/contracts/feature-tests/multi-contract-features/scenarios/external-pure.scen.json b/contracts/feature-tests/multi-contract-features/scenarios/mcf-external-pure.scen.json similarity index 100% rename from contracts/feature-tests/multi-contract-features/scenarios/external-pure.scen.json rename to contracts/feature-tests/multi-contract-features/scenarios/mcf-external-pure.scen.json diff --git a/contracts/feature-tests/multi-contract-features/src/multi_contract_features.rs b/contracts/feature-tests/multi-contract-features/src/multi_contract_features.rs index 07870e8ea2..448e7e5653 100644 --- a/contracts/feature-tests/multi-contract-features/src/multi_contract_features.rs +++ b/contracts/feature-tests/multi-contract-features/src/multi_contract_features.rs @@ -32,4 +32,19 @@ pub trait MultiContractFeatures { fn sample_value_external_set(&self, sample_value: BigUint) { self.sample_value().set(sample_value); } + + #[view] + fn example_feature_message(&self) -> &'static str { + example_feature_message() + } +} + +#[cfg(feature = "example_feature")] +fn example_feature_message() -> &'static str { + "example-feature on" +} + +#[cfg(not(feature = "example_feature"))] +fn example_feature_message() -> &'static str { + "example-feature off" } diff --git a/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_go_test.rs b/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_go_test.rs index 944e4472b8..25bd5bb2bd 100644 --- a/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_go_test.rs +++ b/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_go_test.rs @@ -1,9 +1,14 @@ #[test] -fn external_pure_go() { - multiversx_sc_scenario::run_go("scenarios/external-pure.scen.json"); +fn mcf_example_feature_go() { + multiversx_sc_scenario::run_go("scenarios/mcf-example-feature.scen.json"); } #[test] -fn external_get_go() { - multiversx_sc_scenario::run_go("scenarios/external-get.scen.json"); +fn mcf_external_pure_go() { + multiversx_sc_scenario::run_go("scenarios/mcf-external-pure.scen.json"); +} + +#[test] +fn mcf_external_get_go() { + multiversx_sc_scenario::run_go("scenarios/mcf-external-get.scen.json"); } diff --git a/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_rs_test.rs b/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_rs_test.rs index 858c1f4912..1faffe468d 100644 --- a/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_rs_test.rs +++ b/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_rs_test.rs @@ -19,11 +19,17 @@ fn world() -> ScenarioWorld { } #[test] -fn external_pure_rs() { - multiversx_sc_scenario::run_rs("scenarios/external-pure.scen.json", world()); +#[ignore] // not supported +fn mcf_example_feature_rs() { + multiversx_sc_scenario::run_rs("scenarios/mcf-example-feature.scen.json", world()); } #[test] -fn external_get_rs() { - multiversx_sc_scenario::run_rs("scenarios/external-get.scen.json", world()); +fn mcf_external_pure_rs() { + multiversx_sc_scenario::run_rs("scenarios/mcf-external-pure.scen.json", world()); +} + +#[test] +fn mcf_external_get_rs() { + multiversx_sc_scenario::run_rs("scenarios/mcf-external-get.scen.json", world()); } diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.lock b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.lock new file mode 100644 index 0000000000..dc2be4a12e --- /dev/null +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.lock @@ -0,0 +1,262 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", + "version_check", +] + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + +[[package]] +name = "libc" +version = "0.2.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" + +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + +[[package]] +name = "multi-contract-example-feature-wasm" +version = "0.0.0" +dependencies = [ + "multi-contract-features", + "multiversx-sc-wasm-adapter", +] + +[[package]] +name = "multi-contract-features" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "multiversx-sc" +version = "0.39.5" +dependencies = [ + "bitflags", + "hashbrown", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.17.1" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.17.1" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.39.5" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.39.5" +dependencies = [ + "multiversx-sc", + "wee_alloc", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "proc-macro2" +version = "1.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "memory_units", + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.toml b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.toml new file mode 100644 index 0000000000..c36916d109 --- /dev/null +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "multi-contract-example-feature-wasm" +version = "0.0.0" +authors = ["Andrei Marinica "] +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] +[profile.release] +codegen-units = 1 +opt-level = "z" +lto = true +debug = false +panic = "abort" +[dependencies.multi-contract-features] +path = ".." +features = ["example_feature"] + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.39.5" +path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/src/lib.rs b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/src/lib.rs new file mode 100644 index 0000000000..381742b780 --- /dev/null +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/src/lib.rs @@ -0,0 +1,26 @@ +// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Endpoints: 2 +// Async Callback (empty): 1 +// Total number of exported functions: 4 + +#![no_std] +#![feature(alloc_error_handler, lang_items)] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + multi_contract_features + ( + sample_value + example_feature_message + ) +} + +multiversx_sc_wasm_adapter::empty_callback! {} diff --git a/contracts/feature-tests/multi-contract-features/wasm/src/lib.rs b/contracts/feature-tests/multi-contract-features/wasm/src/lib.rs index 9d1ee2c208..381742b780 100644 --- a/contracts/feature-tests/multi-contract-features/wasm/src/lib.rs +++ b/contracts/feature-tests/multi-contract-features/wasm/src/lib.rs @@ -5,9 +5,9 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 1 +// Endpoints: 2 // Async Callback (empty): 1 -// Total number of exported functions: 3 +// Total number of exported functions: 4 #![no_std] #![feature(alloc_error_handler, lang_items)] @@ -19,6 +19,7 @@ multiversx_sc_wasm_adapter::endpoints! { multi_contract_features ( sample_value + example_feature_message ) } diff --git a/framework/meta/src/cargo_toml_contents.rs b/framework/meta/src/cargo_toml_contents.rs index d0b7f71ba2..288aef548c 100644 --- a/framework/meta/src/cargo_toml_contents.rs +++ b/framework/meta/src/cargo_toml_contents.rs @@ -105,4 +105,30 @@ impl CargoTomlContents { } result } + + pub fn change_features_for_parent_crate_dep(&mut self, features: &[String]) { + let deps_mut = self.dependencies_mut(); + for (_, dep) in deps_mut { + if is_dep_path_above(dep) { + let feature_values = features + .iter() + .map(|feature| Value::String(feature.clone())) + .collect(); + dep.as_table_mut() + .expect("malformed crate Cargo.toml") + .insert("features".to_string(), Value::Array(feature_values)); + } + } + } +} + +/// Checks that path == ".." in a depdency. +fn is_dep_path_above(dep: &Value) -> bool { + if let Some(path) = dep.get("path") { + if let Some(s) = path.as_str() { + return s == ".."; + } + } + + false } diff --git a/framework/meta/src/meta_config.rs b/framework/meta/src/meta_config.rs index 9b5978c643..e94017a4b1 100644 --- a/framework/meta/src/meta_config.rs +++ b/framework/meta/src/meta_config.rs @@ -2,7 +2,9 @@ use std::fs; use multiversx_sc::abi::ContractAbi; -use crate::{meta_wasm_tools::check_tools_installed, CargoTomlContents}; +use crate::{ + meta_wasm_tools::check_tools_installed, output_contract::OutputContract, CargoTomlContents, +}; use super::{cli_args::BuildArgs, output_contract::OutputContractConfig}; @@ -61,14 +63,27 @@ impl MetaConfig { 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.clone()); - cargo_toml_contents.save_to_file(secondary_contract.cargo_toml_path()); + secondary_contract_cargo_toml(secondary_contract, &main_cargo_toml_contents) + .save_to_file(secondary_contract.cargo_toml_path()); } } +} +fn secondary_contract_cargo_toml( + secondary_contract: &OutputContract, + main_cargo_toml_contents: &CargoTomlContents, +) -> CargoTomlContents { + let mut cargo_toml_contents = main_cargo_toml_contents.clone(); + cargo_toml_contents.change_package_name(secondary_contract.wasm_crate_name.clone()); + if !secondary_contract.settings.features.is_empty() { + cargo_toml_contents + .change_features_for_parent_crate_dep(secondary_contract.settings.features.as_slice()); + } + cargo_toml_contents +} + +impl MetaConfig { fn generate_wasm_src_lib(&self) { for output_contract in &self.output_contracts.contracts { output_contract.generate_wasm_src_lib_file(); diff --git a/framework/meta/src/output_contract/multi_contract_serde.rs b/framework/meta/src/output_contract/multi_contract_serde.rs index 2575d4193f..0de0fefeb8 100644 --- a/framework/meta/src/output_contract/multi_contract_serde.rs +++ b/framework/meta/src/output_contract/multi_contract_serde.rs @@ -35,6 +35,9 @@ pub struct OutputContractSerde { #[serde(default)] #[serde(rename = "panic-message")] pub panic_message: Option, + + #[serde(default)] + pub features: Vec, } #[derive(Deserialize, Default, Debug)] diff --git a/framework/meta/src/output_contract/output_contract_builder.rs b/framework/meta/src/output_contract/output_contract_builder.rs index 6bfbed8d88..e6e63bdc2b 100644 --- a/framework/meta/src/output_contract/output_contract_builder.rs +++ b/framework/meta/src/output_contract/output_contract_builder.rs @@ -54,6 +54,7 @@ impl OutputContractBuilder { settings: OutputContractSettings { external_view: cms.external_view.unwrap_or_default(), panic_message: cms.panic_message.unwrap_or_default(), + features: cms.features.clone(), }, ..Default::default() }, @@ -225,6 +226,17 @@ fn set_main_contract_flag( } } +fn validate_output_contracts(contracts: &[OutputContract]) { + for contract in contracts { + if contract.main { + assert!( + contract.settings.features.is_empty(), + "features not supported for main contract" + ); + } + } +} + impl OutputContractConfig { /// Assembles an `OutputContractConfig` from a raw config object that was loaded via Serde. /// @@ -244,6 +256,7 @@ impl OutputContractConfig { .map(|builder| build_contract(builder, original_abi)) .collect(); set_main_contract_flag(&mut contracts, &config.settings.main); + validate_output_contracts(&contracts); OutputContractConfig { default_contract_config_name: config.settings.main.clone().unwrap_or_default(), contracts, diff --git a/framework/meta/src/output_contract/output_contract_model.rs b/framework/meta/src/output_contract/output_contract_model.rs index ecef967b02..b581da142d 100644 --- a/framework/meta/src/output_contract/output_contract_model.rs +++ b/framework/meta/src/output_contract/output_contract_model.rs @@ -74,6 +74,9 @@ pub struct OutputContractSettings { /// Panic messages add a lot of bloat to the final bytecode, /// so they should only be used for debugging purposes. pub panic_message: bool, + + /// Features that are activated on the contract crate, from wasm. + pub features: Vec, } /// Represents a contract created by the framework when building.