Remove gas function from the public API (#1503)

* Disallow importing `gas` function

* Update srml/contract/src/wasm/prepare.rs

Co-Authored-By: pepyakin <s.pepyakin@gmail.com>
This commit is contained in:
Sergei Pepyakin
2019-01-21 16:21:32 +01:00
committed by Bastian Köcher
parent c2f7993d0f
commit 603392a9b9
2 changed files with 29 additions and 4 deletions
+26 -4
View File
@@ -229,7 +229,10 @@ impl<'a, Gas: 'a + As<u32> + Clone> ContractModule<'a, Gas> {
.get(*type_idx as usize)
.ok_or_else(|| "validation: import entry points to a non-existent type")?;
if !C::can_satisfy(import.field().as_bytes(), func_ty) {
// We disallow importing `gas` function here since it is treated as implementation detail.
if import.field().as_bytes() == b"gas"
|| !C::can_satisfy(import.field().as_bytes(), func_ty)
{
return Err("module imports a non-existent function");
}
}
@@ -263,8 +266,6 @@ pub fn prepare_contract<T: Trait, C: ImportSatisfyCheck>(
let mut contract_module = ContractModule::new(original_code, schedule)?;
contract_module.scan_exports()?;
contract_module.ensure_no_internal_memory()?;
contract_module.inject_gas_metering()?;
contract_module.inject_stack_height_metering()?;
struct MemoryDefinition {
initial: u32,
@@ -300,6 +301,9 @@ pub fn prepare_contract<T: Trait, C: ImportSatisfyCheck>(
}
};
contract_module.inject_gas_metering()?;
contract_module.inject_stack_height_metering()?;
Ok(PrefabWasmModule {
schedule_version: schedule.version,
initial: memory_def.initial,
@@ -327,7 +331,11 @@ mod tests {
// implementation from it. So actual implementations doesn't matter.
define_env!(TestEnv, <E: Ext>,
panic(_ctx) => { unreachable!(); },
// gas is an implementation defined function and a contract can't import it.
gas(_ctx, _amount: u32) => { unreachable!(); },
nop(_ctx, _unused: u64) => { unreachable!(); },
);
macro_rules! prepare_test {
@@ -445,7 +453,7 @@ mod tests {
prepare_test!(can_import_legit_function,
r#"
(module
(import "env" "gas" (func (param i32)))
(import "env" "nop" (func (param i64)))
(func (export "call"))
(func (export "deploy"))
@@ -454,6 +462,20 @@ mod tests {
Ok(_)
);
// even though gas is defined the contract can't import it since
// it is an implementation defined.
prepare_test!(can_not_import_gas_function,
r#"
(module
(import "env" "gas" (func (param i32)))
(func (export "call"))
(func (export "deploy"))
)
"#,
Err("module imports a non-existent function")
);
// nothing can be imported from non-"env" module for now.
prepare_test!(non_env_import,
r#"
@@ -202,6 +202,9 @@ define_env!(Env, <E: Ext>,
// Account for used gas. Traps if gas used is greater than gas limit.
//
// NOTE: This is a implementation defined call and is NOT a part of the public API.
// This call is supposed to be called only by instrumentation injected code.
//
// - amount: How much gas is used.
gas(ctx, amount: u32) => {
charge_gas(&mut ctx.gas_meter, ctx.schedule, RuntimeToken::Explicit(amount))?;