Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 982f599

Browse files
atheiagryaznov
andauthored
contracts: Replace cargo feature unstable-interface with config (#12787)
* Replace cargo feature with config * Update frame/contracts/proc-macro/src/lib.rs Co-authored-by: Sasha Gryaznov <[email protected]> Co-authored-by: Sasha Gryaznov <[email protected]>
1 parent 2ed4058 commit 982f599

File tree

10 files changed

+94
-66
lines changed

10 files changed

+94
-66
lines changed

bin/node/runtime/Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,6 @@ try-runtime = [
312312
"pallet-vesting/try-runtime",
313313
"pallet-whitelist/try-runtime",
314314
]
315-
# Make contract callable functions marked as __unstable__ available. Do not enable
316-
# on live chains as those are subject to change.
317-
contracts-unstable-interface = ["pallet-contracts/unstable-interface"]
318315
# Force `sp-sandbox` to call into the host resident executor. One still need to make sure
319316
# that `sc-executor` gets the `wasmer-sandbox` feature which happens automatically when
320317
# specified on the command line.

bin/node/runtime/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use frame_support::{
3232
pallet_prelude::Get,
3333
parameter_types,
3434
traits::{
35-
AsEnsureOriginWithArg, ConstU128, ConstU16, ConstU32, Currency, EitherOfDiverse,
35+
AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32, Currency, EitherOfDiverse,
3636
EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter, KeyOwnerProofSystem,
3737
LockIdentifier, Nothing, OnUnbalanced, U128CurrencyToVote, WithdrawReasons,
3838
},
@@ -1191,6 +1191,7 @@ impl pallet_contracts::Config for Runtime {
11911191
type AddressGenerator = pallet_contracts::DefaultAddressGenerator;
11921192
type MaxCodeLen = ConstU32<{ 128 * 1024 }>;
11931193
type MaxStorageKeyLen = ConstU32<128>;
1194+
type UnsafeUnstableInterface = ConstBool<false>;
11941195
}
11951196

11961197
impl pallet_sudo::Config for Runtime {

frame/contracts/Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,5 @@ runtime-benchmarks = [
8484
"frame-benchmarking/runtime-benchmarks",
8585
"rand",
8686
"rand_pcg",
87-
"unstable-interface",
8887
]
8988
try-runtime = ["frame-support/try-runtime"]
90-
# Make contract callable functions marked as unstable available. Do not enable
91-
# on live chains as those are subject to change.
92-
unstable-interface = []

frame/contracts/README.md

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,11 @@ this pallet contains the concept of an unstable interface. Akin to the rust nigh
142142
it allows us to add new interfaces but mark them as unstable so that contract languages can
143143
experiment with them and give feedback before we stabilize those.
144144

145-
In order to access interfaces marked as `#[unstable]` in `runtime.rs` one need to compile
146-
this crate with the `unstable-interface` feature enabled. It should be obvious that any
147-
live runtime should never be compiled with this feature: In addition to be subject to
148-
change or removal those interfaces do not have proper weights associated with them and
149-
are therefore considered unsafe.
150-
151-
The substrate runtime exposes this feature as `contracts-unstable-interface`. Example
152-
commandline for running the substrate node with unstable contracts interfaces:
153-
154-
```bash
155-
cargo run --release --features contracts-unstable-interface -- --dev
156-
```
145+
In order to access interfaces marked as `#[unstable]` in `runtime.rs` one need to set
146+
`pallet_contracts::Config::UnsafeUnstableInterface` to `ConstU32<true>`. It should be obvious
147+
that any production runtime should never be compiled with this feature: In addition to be
148+
subject to change or removal those interfaces might not have proper weights associated with
149+
them and are therefore considered unsafe.
157150

158151
New interfaces are generally added as unstable and might go through several iterations
159152
before they are promoted to a stable interface.

frame/contracts/proc-macro/src/lib.rs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ struct HostFn {
157157
module: String,
158158
name: String,
159159
returns: HostFnReturn,
160-
is_unstable: bool,
160+
is_stable: bool,
161161
}
162162

163163
enum HostFnReturn {
@@ -199,7 +199,7 @@ impl HostFn {
199199
attrs.retain(|a| !(a.path.is_ident("doc") || a.path.is_ident("prefixed_alias")));
200200
let name = item.sig.ident.to_string();
201201
let mut maybe_module = None;
202-
let mut is_unstable = false;
202+
let mut is_stable = true;
203203
while let Some(attr) = attrs.pop() {
204204
let ident = attr.path.get_ident().ok_or(err(span, msg))?.to_string();
205205
match ident.as_str() {
@@ -212,10 +212,10 @@ impl HostFn {
212212
maybe_module = Some(format!("seal{}", ver));
213213
},
214214
"unstable" => {
215-
if is_unstable {
215+
if !is_stable {
216216
return Err(err(span, "#[unstable] can only be specified once"))
217217
}
218-
is_unstable = true;
218+
is_stable = false;
219219
},
220220
_ => return Err(err(span, msg)),
221221
}
@@ -312,7 +312,7 @@ impl HostFn {
312312
module: maybe_module.unwrap_or_else(|| "seal0".to_string()),
313313
name,
314314
returns,
315-
is_unstable,
315+
is_stable,
316316
})
317317
},
318318
_ => Err(err(span, &msg)),
@@ -406,15 +406,15 @@ fn expand_impls(def: &mut EnvDef) -> TokenStream2 {
406406
<E::T as ::frame_system::Config>::AccountId:
407407
::sp_core::crypto::UncheckedFrom<<E::T as ::frame_system::Config>::Hash> + ::core::convert::AsRef<[::core::primitive::u8]>,
408408
{
409-
fn define(store: &mut ::wasmi::Store<crate::wasm::Runtime<E>>, linker: &mut ::wasmi::Linker<crate::wasm::Runtime<E>>) -> Result<(), ::wasmi::errors::LinkerError> {
409+
fn define(store: &mut ::wasmi::Store<crate::wasm::Runtime<E>>, linker: &mut ::wasmi::Linker<crate::wasm::Runtime<E>>, allow_unstable: bool) -> Result<(), ::wasmi::errors::LinkerError> {
410410
#impls
411411
Ok(())
412412
}
413413
}
414414

415415
impl crate::wasm::Environment<()> for Env
416416
{
417-
fn define(store: &mut ::wasmi::Store<()>, linker: &mut ::wasmi::Linker<()>) -> Result<(), ::wasmi::errors::LinkerError> {
417+
fn define(store: &mut ::wasmi::Store<()>, linker: &mut ::wasmi::Linker<()>, allow_unstable: bool) -> Result<(), ::wasmi::errors::LinkerError> {
418418
#dummy_impls
419419
Ok(())
420420
}
@@ -437,10 +437,7 @@ fn expand_functions(
437437
f.returns.to_wasm_sig(),
438438
&f.item.sig.output
439439
);
440-
let unstable_feat = match f.is_unstable {
441-
true => quote! { #[cfg(feature = "unstable-interface")] },
442-
false => quote! {},
443-
};
440+
let is_stable = f.is_stable;
444441

445442
// If we don't expand blocks (implementing for `()`) we change a few things:
446443
// - We replace any code by unreachable!
@@ -480,16 +477,18 @@ fn expand_functions(
480477
quote! { #[allow(unused_variables)] }
481478
};
482479

483-
484480
quote! {
485-
#unstable_feat
486-
#allow_unused
487-
linker.define(#module, #name, ::wasmi::Func::wrap(&mut*store, |mut __caller__: ::wasmi::Caller<#host_state>, #( #params, )*| -> #wasm_output {
488-
let mut func = #inner;
489-
func()
490-
.map_err(#map_err)
491-
.map(::core::convert::Into::into)
492-
}))?;
481+
// We need to allow unstable functions when runtime benchmarks are performed because
482+
// we generate the weights even when those interfaces are not enabled.
483+
if ::core::cfg!(feature = "runtime-benchmarks") || #is_stable || allow_unstable {
484+
#allow_unused
485+
linker.define(#module, #name, ::wasmi::Func::wrap(&mut*store, |mut __caller__: ::wasmi::Caller<#host_state>, #( #params, )*| -> #wasm_output {
486+
let mut func = #inner;
487+
func()
488+
.map_err(#map_err)
489+
.map(::core::convert::Into::into)
490+
}))?;
491+
}
493492
}
494493
});
495494
quote! {

frame/contracts/src/benchmarking/sandbox.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ where
6464
struct EmptyEnv;
6565

6666
impl Environment<()> for EmptyEnv {
67-
fn define(_store: &mut Store<()>, _linker: &mut Linker<()>) -> Result<(), LinkerError> {
67+
fn define(_: &mut Store<()>, _: &mut Linker<()>, _: bool) -> Result<(), LinkerError> {
6868
Ok(())
6969
}
7070
}

frame/contracts/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,24 @@ pub mod pallet {
326326
/// The maximum length of a contract code in bytes. This limit applies to the instrumented
327327
/// version of the code. Therefore `instantiate_with_code` can fail even when supplying
328328
/// a wasm binary below this maximum size.
329+
#[pallet::constant]
329330
type MaxCodeLen: Get<u32>;
330331

331332
/// The maximum allowable length in bytes for storage keys.
333+
#[pallet::constant]
332334
type MaxStorageKeyLen: Get<u32>;
335+
336+
/// Make contract callable functions marked as `#[unstable]` available.
337+
///
338+
/// Contracts that use `#[unstable]` functions won't be able to be uploaded unless
339+
/// this is set to `true`. This is only meant for testnets and dev nodes in order to
340+
/// experiment with new features.
341+
///
342+
/// # Warning
343+
///
344+
/// Do **not** set to `true` on productions chains.
345+
#[pallet::constant]
346+
type UnsafeUnstableInterface: Get<bool>;
333347
}
334348

335349
#[pallet::hooks]

frame/contracts/src/tests.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ pub mod test_utils {
122122
}
123123
}
124124

125+
impl Test {
126+
pub fn set_unstable_interface(unstable_interface: bool) {
127+
UNSTABLE_INTERFACE.with(|v| *v.borrow_mut() = unstable_interface);
128+
}
129+
}
130+
125131
parameter_types! {
126132
static TestExtensionTestValue: TestExtension = Default::default();
127133
}
@@ -385,6 +391,7 @@ impl Contains<RuntimeCall> for TestFilter {
385391

386392
parameter_types! {
387393
pub const DeletionWeightLimit: Weight = Weight::from_ref_time(500_000_000_000);
394+
pub static UnstableInterface: bool = true;
388395
}
389396

390397
impl Config for Test {
@@ -407,6 +414,7 @@ impl Config for Test {
407414
type AddressGenerator = DefaultAddressGenerator;
408415
type MaxCodeLen = ConstU32<{ 128 * 1024 }>;
409416
type MaxStorageKeyLen = ConstU32<128>;
417+
type UnsafeUnstableInterface = UnstableInterface;
410418
}
411419

412420
pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]);
@@ -2687,7 +2695,6 @@ fn gas_estimation_nested_call_fixed_limit() {
26872695
}
26882696

26892697
#[test]
2690-
#[cfg(feature = "unstable-interface")]
26912698
fn gas_estimation_call_runtime() {
26922699
use codec::Decode;
26932700
let (caller_code, caller_hash) = compile_module::<Test>("call_runtime").unwrap();
@@ -4411,7 +4418,6 @@ fn delegate_call_indeterministic_code() {
44114418
}
44124419

44134420
#[test]
4414-
#[cfg(feature = "unstable-interface")]
44154421
fn reentrance_count_works_with_call() {
44164422
let (wasm, code_hash) = compile_module::<Test>("reentrance_count_call").unwrap();
44174423
let contract_addr = Contracts::contract_address(&ALICE, &code_hash, &[]);
@@ -4448,7 +4454,6 @@ fn reentrance_count_works_with_call() {
44484454
}
44494455

44504456
#[test]
4451-
#[cfg(feature = "unstable-interface")]
44524457
fn reentrance_count_works_with_delegated_call() {
44534458
let (wasm, code_hash) = compile_module::<Test>("reentrance_count_delegated_call").unwrap();
44544459
let contract_addr = Contracts::contract_address(&ALICE, &code_hash, &[]);
@@ -4485,7 +4490,6 @@ fn reentrance_count_works_with_delegated_call() {
44854490
}
44864491

44874492
#[test]
4488-
#[cfg(feature = "unstable-interface")]
44894493
fn account_reentrance_count_works() {
44904494
let (wasm, code_hash) = compile_module::<Test>("account_reentrance_count_call").unwrap();
44914495
let (wasm_reentrance_count, code_hash_reentrance_count) =

0 commit comments

Comments
 (0)