diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 4d4140aedc..7aed887a5b 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -2156,6 +2156,7 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", + "srml-contracts 2.0.0", "srml-finality-tracker 2.0.0", "srml-indices 2.0.0", "srml-timestamp 2.0.0", diff --git a/substrate/node/cli/Cargo.toml b/substrate/node/cli/Cargo.toml index 267ec2cea0..79042f6043 100644 --- a/substrate/node/cli/Cargo.toml +++ b/substrate/node/cli/Cargo.toml @@ -38,6 +38,7 @@ indices = { package = "srml-indices", path = "../../srml/indices" } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default-features = false } rand = "0.6" finality_tracker = { package = "srml-finality-tracker", path = "../../srml/finality-tracker", default-features = false } +contracts = { package = "srml-contracts", path = "../../srml/contracts" } [dev-dependencies] consensus-common = { package = "substrate-consensus-common", path = "../../core/consensus/common" } diff --git a/substrate/node/cli/src/chain_spec.rs b/substrate/node/cli/src/chain_spec.rs index 672c75b1a9..ace9a18a45 100644 --- a/substrate/node/cli/src/chain_spec.rs +++ b/substrate/node/cli/src/chain_spec.rs @@ -174,12 +174,14 @@ fn staging_testnet_config_genesis() -> GenesisConfig { transfer_fee: 1 * CENTS, creation_fee: 1 * CENTS, contract_fee: 1 * CENTS, - call_base_fee: 1000, - create_base_fee: 1000, gas_price: 1 * MILLICENTS, max_depth: 1024, block_gas_limit: 10_000_000, - current_schedule: Default::default(), + current_schedule: contracts::Schedule { + call_base_cost: 1000, + instantiate_base_cost: 1000, + ..Default::default() + }, }), sudo: Some(SudoConfig { key: endowed_accounts[0].clone(), @@ -268,27 +270,6 @@ pub fn testnet_genesis( const ENDOWMENT: u128 = 1 << 20; let council_desired_seats = (endowed_accounts.len() / 2 - initial_authorities.len()) as u32; - let mut contracts_config = ContractsConfig { - signed_claim_handicap: 2, - rent_byte_price: 4, - rent_deposit_offset: 1000, - storage_size_offset: 8, - surcharge_reward: 150, - tombstone_deposit: 16, - transaction_base_fee: 1, - transaction_byte_fee: 0, - transfer_fee: 0, - creation_fee: 0, - contract_fee: 21, - call_base_fee: 135, - create_base_fee: 175, - gas_price: 1, - max_depth: 1024, - block_gas_limit: 10_000_000, - current_schedule: Default::default(), - }; - // this should only be enabled on development chains - contracts_config.current_schedule.enable_println = enable_println; GenesisConfig { system: Some(SystemConfig { @@ -349,7 +330,26 @@ pub fn testnet_genesis( spend_period: 12 * 60 * 24, burn: Permill::from_percent(50), }), - contracts: Some(contracts_config), + contracts: Some(ContractsConfig { + signed_claim_handicap: 2, + rent_byte_price: 4, + rent_deposit_offset: 1000, + storage_size_offset: 8, + surcharge_reward: 150, + tombstone_deposit: 16, + transaction_base_fee: 1, + transaction_byte_fee: 0, + transfer_fee: 0, + creation_fee: 0, + contract_fee: 21, + gas_price: 1, + max_depth: 1024, + block_gas_limit: 10_000_000, + current_schedule: contracts::Schedule { + enable_println, // this should only be enabled on development chains + ..Default::default() + }, + }), sudo: Some(SudoConfig { key: root_key, }), diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index d35839cfaa..ac0fa136ff 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -58,8 +58,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("node"), impl_name: create_runtime_str!("substrate-node"), authoring_version: 10, - spec_version: 98, - impl_version: 101, + spec_version: 99, + impl_version: 102, apis: RUNTIME_API_VERSIONS, }; @@ -221,7 +221,6 @@ impl contracts::Trait for Runtime { type Currency = Balances; type Call = Call; type Event = Event; - type Gas = u64; type DetermineContractAddress = contracts::SimpleAddressDeterminator; type ComputeDispatchFee = contracts::DefaultDispatchFeeComputor; type TrieIdGenerator = contracts::TrieIdFromParentCounter; diff --git a/substrate/srml/contracts/src/exec.rs b/substrate/srml/contracts/src/exec.rs index 7a16c9d60d..c9573152de 100644 --- a/substrate/srml/contracts/src/exec.rs +++ b/substrate/srml/contracts/src/exec.rs @@ -17,7 +17,7 @@ use super::{CodeHash, Config, ContractAddressFor, Event, RawEvent, Trait, TrieId, BalanceOf, ContractInfoOf}; use crate::account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}; -use crate::gas::{GasMeter, Token, approx_gas_for_balance}; +use crate::gas::{Gas, GasMeter, Token, approx_gas_for_balance}; use rstd::prelude::*; use runtime_primitives::traits::{Bounded, CheckedAdd, CheckedSub, Zero}; @@ -239,10 +239,10 @@ pub enum ExecFeeToken { impl Token for ExecFeeToken { type Metadata = Config; #[inline] - fn calculate_amount(&self, metadata: &Config) -> T::Gas { + fn calculate_amount(&self, metadata: &Config) -> Gas { match *self { - ExecFeeToken::Call => metadata.call_base_fee, - ExecFeeToken::Instantiate => metadata.instantiate_base_fee, + ExecFeeToken::Call => metadata.schedule.call_base_cost, + ExecFeeToken::Instantiate => metadata.schedule.instantiate_base_cost, } } } @@ -465,13 +465,13 @@ impl Token for TransferFeeToken> { type Metadata = Config; #[inline] - fn calculate_amount(&self, metadata: &Config) -> T::Gas { + fn calculate_amount(&self, metadata: &Config) -> Gas { let balance_fee = match self.kind { TransferFeeKind::ContractInstantiate => metadata.contract_account_instantiate_fee, TransferFeeKind::AccountCreate => metadata.account_create_fee, TransferFeeKind::Transfer => metadata.transfer_fee, }; - approx_gas_for_balance::(self.gas_price, balance_fee) + approx_gas_for_balance(self.gas_price, balance_fee) } } @@ -491,7 +491,7 @@ enum TransferCause { /// is specified using the `cause` parameter. /// /// NOTE: that the fee is denominated in `BalanceOf` units, but -/// charged in `T::Gas` from the provided `gas_meter`. This means +/// charged in `Gas` from the provided `gas_meter`. This means /// that the actual amount charged might differ. /// /// NOTE: that we allow for draining all funds of the contract so it diff --git a/substrate/srml/contracts/src/gas.rs b/substrate/srml/contracts/src/gas.rs index 94688ea27f..1251584b55 100644 --- a/substrate/srml/contracts/src/gas.rs +++ b/substrate/srml/contracts/src/gas.rs @@ -15,13 +15,18 @@ // along with Substrate. If not, see . use crate::{GasSpent, Module, Trait, BalanceOf, NegativeImbalanceOf}; +use rstd::convert::TryFrom; use runtime_primitives::BLOCK_FULL; -use runtime_primitives::traits::{CheckedMul, CheckedSub, Zero, SaturatedConversion}; +use runtime_primitives::traits::{CheckedMul, Zero, SaturatedConversion, SimpleArithmetic, UniqueSaturatedInto}; use srml_support::{StorageValue, traits::{OnUnbalanced, ExistenceRequirement, WithdrawReason, Currency, Imbalance}}; #[cfg(test)] use std::{any::Any, fmt::Debug}; +// Gas units are chosen to be represented by u64 so that gas metering instructions can operate on +// them efficiently. +pub type Gas = u64; + #[must_use] #[derive(Debug, PartialEq, Eq)] pub enum GasMeterResult { @@ -68,7 +73,7 @@ pub trait Token: Copy + Clone + TestAuxiliaries { /// That said, implementors of this function still can run into overflows /// while calculating the amount. In this case it is ok to use saturating operations /// since on overflow they will return `max_value` which should consume all gas. - fn calculate_amount(&self, metadata: &Self::Metadata) -> T::Gas; + fn calculate_amount(&self, metadata: &Self::Metadata) -> Gas; } /// A wrapper around a type-erased trait object of what used to be a `Token`. @@ -79,9 +84,9 @@ pub struct ErasedToken { } pub struct GasMeter { - limit: T::Gas, + limit: Gas, /// Amount of gas left from initial gas limit. Can reach zero. - gas_left: T::Gas, + gas_left: Gas, gas_price: BalanceOf, #[cfg(test)] @@ -89,7 +94,7 @@ pub struct GasMeter { } impl GasMeter { #[cfg(test)] - pub fn with_limit(gas_limit: T::Gas, gas_price: BalanceOf) -> GasMeter { + pub fn with_limit(gas_limit: Gas, gas_price: BalanceOf) -> GasMeter { GasMeter { limit: gas_limit, gas_left: gas_limit, @@ -125,7 +130,7 @@ impl GasMeter { } let amount = token.calculate_amount(metadata); - let new_value = match self.gas_left.checked_sub(&amount) { + let new_value = match self.gas_left.checked_sub(amount) { None => None, Some(val) => Some(val), }; @@ -148,7 +153,7 @@ impl GasMeter { /// All unused gas in the nested gas meter is returned to this gas meter. pub fn with_nested>) -> R>( &mut self, - amount: T::Gas, + amount: Gas, f: F, ) -> R { // NOTE that it is ok to allocate all available gas since it still ensured @@ -178,12 +183,12 @@ impl GasMeter { } /// Returns how much gas left from the initial budget. - pub fn gas_left(&self) -> T::Gas { + pub fn gas_left(&self) -> Gas { self.gas_left } /// Returns how much gas was spent. - fn spent(&self) -> T::Gas { + fn spent(&self) -> Gas { self.limit - self.gas_left } @@ -199,7 +204,7 @@ impl GasMeter { /// The funds are deducted from `transactor`. pub fn buy_gas( transactor: &T::AccountId, - gas_limit: T::Gas, + gas_limit: Gas, ) -> Result<(GasMeter, NegativeImbalanceOf), &'static str> { // Check if the specified amount of gas is available in the current block. // This cannot underflow since `gas_spent` is never greater than `block_gas_limit`. @@ -211,9 +216,13 @@ pub fn buy_gas( // Buy the specified amount of gas. let gas_price = >::gas_price(); - let cost = gas_limit.clone().into() - .checked_mul(&gas_price) - .ok_or("overflow multiplying gas limit by price")?; + let cost = if gas_price.is_zero() { + >::zero() + } else { + as TryFrom>::try_from(gas_limit).ok() + .and_then(|gas_limit| gas_price.checked_mul(&gas_limit)) + .ok_or("overflow multiplying gas limit by price")? + }; let imbalance = T::Currency::withdraw( transactor, @@ -243,11 +252,11 @@ pub fn refund_unused_gas( // Increase total spent gas. // This cannot overflow, since `gas_spent` is never greater than `block_gas_limit`, which - // also has T::Gas type. + // also has Gas type. >::mutate(|block_gas_spent| *block_gas_spent += gas_spent); // Refund gas left by the price it was bought at. - let refund = gas_left.into() * gas_meter.gas_price; + let refund = gas_meter.gas_price * gas_left.unique_saturated_into(); let refund_imbalance = T::Currency::deposit_creating(transactor, refund); if let Ok(imbalance) = imbalance.offset(refund_imbalance) { T::GasPayment::on_unbalanced(imbalance); @@ -256,8 +265,10 @@ pub fn refund_unused_gas( /// A little handy utility for converting a value in balance units into approximate value in gas units /// at the given gas price. -pub fn approx_gas_for_balance(gas_price: BalanceOf, balance: BalanceOf) -> T::Gas { - (balance / gas_price).saturated_into::() +pub fn approx_gas_for_balance(gas_price: Balance, balance: Balance) -> Gas + where Balance: SimpleArithmetic +{ + (balance / gas_price).saturated_into::() } /// A simple utility macro that helps to match against a diff --git a/substrate/srml/contracts/src/lib.rs b/substrate/srml/contracts/src/lib.rs index b9c8976cc0..629b8c866d 100644 --- a/substrate/srml/contracts/src/lib.rs +++ b/substrate/srml/contracts/src/lib.rs @@ -90,15 +90,16 @@ mod tests; use crate::exec::ExecutionContext; use crate::account_db::{AccountDb, DirectAccountDb}; +use crate::gas::Gas; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use substrate_primitives::crypto::UncheckedFrom; -use rstd::{prelude::*, marker::PhantomData, convert::TryFrom}; +use rstd::{prelude::*, marker::PhantomData}; use parity_codec::{Codec, Encode, Decode}; use runtime_io::blake2_256; use runtime_primitives::traits::{ - Hash, SimpleArithmetic, Bounded, StaticLookup, Zero, MaybeSerializeDebug, Member + Hash, StaticLookup, Zero, MaybeSerializeDebug, Member }; use srml_support::dispatch::{Result, Dispatchable}; use srml_support::{ @@ -287,9 +288,6 @@ pub trait Trait: timestamp::Trait { /// The overarching event type. type Event: From> + Into<::Event>; - type Gas: Parameter + Default + Codec + SimpleArithmetic + Bounded + Copy + - Into> + TryFrom>; - /// A function type to get the contract address given the creator. type DetermineContractAddress: ContractAddressFor, Self::AccountId>; @@ -349,7 +347,7 @@ decl_module! { /// Updates the schedule for metering contracts. /// /// The schedule must have a greater version than the stored schedule. - pub fn update_schedule(schedule: Schedule) -> Result { + pub fn update_schedule(schedule: Schedule) -> Result { if >::current_schedule().version >= schedule.version { return Err("new schedule must have a greater version than current"); } @@ -364,7 +362,7 @@ decl_module! { /// You can instantiate contracts only with stored code. pub fn put_code( origin, - #[compact] gas_limit: T::Gas, + #[compact] gas_limit: Gas, code: Vec ) -> Result { let origin = ensure_signed(origin)?; @@ -393,7 +391,7 @@ decl_module! { origin, dest: ::Source, #[compact] value: BalanceOf, - #[compact] gas_limit: T::Gas, + #[compact] gas_limit: Gas, data: Vec ) -> Result { let origin = ensure_signed(origin)?; @@ -453,7 +451,7 @@ decl_module! { pub fn create( origin, #[compact] endowment: BalanceOf, - #[compact] gas_limit: T::Gas, + #[compact] gas_limit: Gas, code_hash: CodeHash, data: Vec ) -> Result { @@ -679,20 +677,16 @@ decl_storage! { TransactionByteFee get(transaction_byte_fee) config(): BalanceOf; /// The fee required to create a contract instance. ContractFee get(contract_fee) config(): BalanceOf = 21.into(); - /// The base fee charged for calling into a contract. - CallBaseFee get(call_base_fee) config(): T::Gas = 135.into(); - /// The base fee charged for creating a contract. - CreateBaseFee get(create_base_fee) config(): T::Gas = 175.into(); /// The price of one unit of gas. GasPrice get(gas_price) config(): BalanceOf = 1.into(); /// The maximum nesting level of a call/create stack. MaxDepth get(max_depth) config(): u32 = 100; /// The maximum amount of gas that could be expended per block. - BlockGasLimit get(block_gas_limit) config(): T::Gas = 10_000_000.into(); + BlockGasLimit get(block_gas_limit) config(): Gas = 10_000_000; /// Gas spent so far in this block. - GasSpent get(gas_spent): T::Gas; + GasSpent get(gas_spent): Gas; /// Current cost schedule for contracts. - CurrentSchedule get(current_schedule) config(): Schedule = Schedule::default(); + CurrentSchedule get(current_schedule) config(): Schedule = Schedule::default(); /// A mapping from an original code hash to the original code, untouched by instrumentation. pub PristineCode: map CodeHash => Option>; /// A mapping between an original code hash and instrumented wasm code, ready for execution. @@ -718,14 +712,12 @@ impl OnFreeBalanceZero for Module { /// We assume that these values can't be changed in the /// course of transaction execution. pub struct Config { - pub schedule: Schedule, + pub schedule: Schedule, pub existential_deposit: BalanceOf, pub max_depth: u32, pub contract_account_instantiate_fee: BalanceOf, pub account_create_fee: BalanceOf, pub transfer_fee: BalanceOf, - pub call_base_fee: T::Gas, - pub instantiate_base_fee: T::Gas, } impl Config { @@ -737,8 +729,6 @@ impl Config { contract_account_instantiate_fee: >::contract_fee(), account_create_fee: >::creation_fee(), transfer_fee: >::transfer_fee(), - call_base_fee: >::call_base_fee(), - instantiate_base_fee: >::create_base_fee(), } } } @@ -746,7 +736,7 @@ impl Config { /// Definition of the cost schedule and other parameterizations for wasm vm. #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] #[derive(Clone, Encode, Decode, PartialEq, Eq)] -pub struct Schedule { +pub struct Schedule { /// Version of the schedule. pub version: u32, @@ -771,6 +761,12 @@ pub struct Schedule { /// Gas cost to deposit an event; the base. pub event_base_cost: Gas, + /// Base gas cost to call into a contract. + pub call_base_cost: Gas, + + /// Base gas cost to instantiate a contract. + pub instantiate_base_cost: Gas, + /// Gas cost per one byte read from the sandbox memory. pub sandbox_data_read_cost: Gas, @@ -797,19 +793,21 @@ pub struct Schedule { pub max_subject_len: u32, } -impl> Default for Schedule { - fn default() -> Schedule { +impl Default for Schedule { + fn default() -> Schedule { Schedule { version: 0, - put_code_per_byte_cost: 1.into(), - grow_mem_cost: 1.into(), - regular_op_cost: 1.into(), - return_data_per_byte_cost: 1.into(), - event_data_per_byte_cost: 1.into(), - event_per_topic_cost: 1.into(), - event_base_cost: 1.into(), - sandbox_data_read_cost: 1.into(), - sandbox_data_write_cost: 1.into(), + put_code_per_byte_cost: 1, + grow_mem_cost: 1, + regular_op_cost: 1, + return_data_per_byte_cost: 1, + event_data_per_byte_cost: 1, + event_per_topic_cost: 1, + event_base_cost: 1, + call_base_cost: 135, + instantiate_base_cost: 175, + sandbox_data_read_cost: 1, + sandbox_data_write_cost: 1, max_event_topics: 4, max_stack_height: 64 * 1024, max_memory_pages: 16, diff --git a/substrate/srml/contracts/src/tests.rs b/substrate/srml/contracts/src/tests.rs index ef4347caff..de3c32d814 100644 --- a/substrate/srml/contracts/src/tests.rs +++ b/substrate/srml/contracts/src/tests.rs @@ -93,7 +93,6 @@ impl timestamp::Trait for Test { impl Trait for Test { type Currency = Balances; type Call = Call; - type Gas = u64; type DetermineContractAddress = DummyContractAddressFor; type Event = MetaEvent; type ComputeDispatchFee = DummyComputeDispatchFee; @@ -215,8 +214,6 @@ impl ExtBuilder { transfer_fee: self.transfer_fee, creation_fee: self.creation_fee, contract_fee: 21, - call_base_fee: 135, - create_base_fee: 175, gas_price: self.gas_price, max_depth: 100, block_gas_limit: self.block_gas_limit, diff --git a/substrate/srml/contracts/src/wasm/code_cache.rs b/substrate/srml/contracts/src/wasm/code_cache.rs index 30c02ef942..140878f28b 100644 --- a/substrate/srml/contracts/src/wasm/code_cache.rs +++ b/substrate/srml/contracts/src/wasm/code_cache.rs @@ -26,11 +26,11 @@ //! this guarantees that every instrumented contract code in cache cannot have the version equal to the current one. //! Thus, before executing a contract it should be reinstrument with new schedule. -use crate::gas::{GasMeter, Token}; +use crate::gas::{Gas, GasMeter, Token}; use crate::wasm::{prepare, runtime::Env, PrefabWasmModule}; use crate::{CodeHash, CodeStorage, PristineCode, Schedule, Trait}; use rstd::prelude::*; -use runtime_primitives::traits::{CheckedMul, Hash, Bounded}; +use runtime_primitives::traits::{Hash, Bounded}; use srml_support::StorageMap; /// Gas metering token that used for charging storing code into the code storage. @@ -41,12 +41,12 @@ use srml_support::StorageMap; pub struct PutCodeToken(u32); impl Token for PutCodeToken { - type Metadata = Schedule; + type Metadata = Schedule; - fn calculate_amount(&self, metadata: &Schedule) -> T::Gas { + fn calculate_amount(&self, metadata: &Schedule) -> Gas { metadata .put_code_per_byte_cost - .checked_mul(&self.0.into()) + .checked_mul(self.0.into()) .unwrap_or_else(|| Bounded::max_value()) } } @@ -58,7 +58,7 @@ impl Token for PutCodeToken { pub fn save( original_code: Vec, gas_meter: &mut GasMeter, - schedule: &Schedule, + schedule: &Schedule, ) -> Result, &'static str> { // The first time instrumentation is on the user. However, consequent reinstrumentation // due to the schedule changes is on governance system. @@ -69,7 +69,7 @@ pub fn save( return Err("there is not enough gas for storing the code"); } - let prefab_module = prepare::prepare_contract::(&original_code, schedule)?; + let prefab_module = prepare::prepare_contract::(&original_code, schedule)?; let code_hash = T::Hashing::hash(&original_code); >::insert(code_hash, prefab_module); @@ -85,7 +85,7 @@ pub fn save( /// re-instrumentation and update the cache in the storage. pub fn load( code_hash: &CodeHash, - schedule: &Schedule, + schedule: &Schedule, ) -> Result { let mut prefab_module = >::get(code_hash).ok_or_else(|| "code is not found")?; @@ -97,7 +97,7 @@ pub fn load( // We need to re-instrument the code with the latest schedule here. let original_code = >::get(code_hash).ok_or_else(|| "pristine code is not found")?; - prefab_module = prepare::prepare_contract::(&original_code, schedule)?; + prefab_module = prepare::prepare_contract::(&original_code, schedule)?; >::insert(code_hash, prefab_module.clone()); } Ok(prefab_module) diff --git a/substrate/srml/contracts/src/wasm/env_def/macros.rs b/substrate/srml/contracts/src/wasm/env_def/macros.rs index 32d02f5abe..4f8bce9904 100644 --- a/substrate/srml/contracts/src/wasm/env_def/macros.rs +++ b/substrate/srml/contracts/src/wasm/env_def/macros.rs @@ -200,7 +200,7 @@ mod tests { use crate::wasm::tests::MockExt; use crate::wasm::Runtime; use crate::exec::Ext; - use crate::Trait; + use crate::gas::Gas; #[test] fn macro_unmarshall_then_body_then_marshall_value_or_trap() { @@ -256,7 +256,7 @@ mod tests { #[test] fn macro_define_func() { define_func!( ext_gas (_ctx, amount: u32) => { - let amount = ::Gas::from(amount); + let amount = Gas::from(amount); if !amount.is_zero() { Ok(()) } else { @@ -308,7 +308,7 @@ mod tests { define_env!(Env, , ext_gas( _ctx, amount: u32 ) => { - let amount = ::Gas::from(amount); + let amount = Gas::from(amount); if !amount.is_zero() { Ok(()) } else { diff --git a/substrate/srml/contracts/src/wasm/mod.rs b/substrate/srml/contracts/src/wasm/mod.rs index 28f71dc9df..40e873542b 100644 --- a/substrate/srml/contracts/src/wasm/mod.rs +++ b/substrate/srml/contracts/src/wasm/mod.rs @@ -63,17 +63,17 @@ pub struct WasmExecutable { } /// Loader which fetches `WasmExecutable` from the code cache. -pub struct WasmLoader<'a, T: Trait> { - schedule: &'a Schedule, +pub struct WasmLoader<'a> { + schedule: &'a Schedule, } -impl<'a, T: Trait> WasmLoader<'a, T> { - pub fn new(schedule: &'a Schedule) -> Self { +impl<'a> WasmLoader<'a> { + pub fn new(schedule: &'a Schedule) -> Self { WasmLoader { schedule } } } -impl<'a, T: Trait> crate::exec::Loader for WasmLoader<'a, T> { +impl<'a, T: Trait> crate::exec::Loader for WasmLoader<'a> { type Executable = WasmExecutable; fn load_init(&self, code_hash: &CodeHash) -> Result { @@ -93,17 +93,17 @@ impl<'a, T: Trait> crate::exec::Loader for WasmLoader<'a, T> { } /// Implementation of `Vm` that takes `WasmExecutable` and executes it. -pub struct WasmVm<'a, T: Trait> { - schedule: &'a Schedule, +pub struct WasmVm<'a> { + schedule: &'a Schedule, } -impl<'a, T: Trait> WasmVm<'a, T> { - pub fn new(schedule: &'a Schedule) -> Self { +impl<'a> WasmVm<'a> { + pub fn new(schedule: &'a Schedule) -> Self { WasmVm { schedule } } } -impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a, T> { +impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a> { type Executable = WasmExecutable; fn execute>( @@ -303,9 +303,9 @@ mod tests { use crate::exec::Vm; let wasm = wabt::wat2wasm(wat).unwrap(); - let schedule = crate::Schedule::::default(); + let schedule = crate::Schedule::default(); let prefab_module = - prepare_contract::(&wasm, &schedule).unwrap(); + prepare_contract::(&wasm, &schedule).unwrap(); let exec = WasmExecutable { // Use a "call" convention. diff --git a/substrate/srml/contracts/src/wasm/prepare.rs b/substrate/srml/contracts/src/wasm/prepare.rs index d780cc1a28..d141cd6b52 100644 --- a/substrate/srml/contracts/src/wasm/prepare.rs +++ b/substrate/srml/contracts/src/wasm/prepare.rs @@ -20,33 +20,33 @@ use crate::wasm::env_def::ImportSatisfyCheck; use crate::wasm::PrefabWasmModule; -use crate::{Schedule, Trait}; +use crate::Schedule; use parity_wasm::elements::{self, Internal, External, MemoryType, Type}; use pwasm_utils; use pwasm_utils::rules; use rstd::prelude::*; -use runtime_primitives::traits::{UniqueSaturatedInto, SaturatedConversion}; +use runtime_primitives::traits::{SaturatedConversion}; -struct ContractModule<'a, Gas: 'a> { +struct ContractModule<'a> { /// A deserialized module. The module is valid (this is Guaranteed by `new` method). /// /// An `Option` is used here for loaning (`take()`-ing) the module. /// Invariant: Can't be `None` (i.e. on enter and on exit from the function /// the value *must* be `Some`). module: Option, - schedule: &'a Schedule, + schedule: &'a Schedule, } -impl<'a, Gas: 'a + From + UniqueSaturatedInto + Clone> ContractModule<'a, Gas> { +impl<'a> ContractModule<'a> { /// Creates a new instance of `ContractModule`. /// /// Returns `Err` if the `original_code` couldn't be decoded or /// if it contains an invalid module. fn new( original_code: &[u8], - schedule: &'a Schedule, - ) -> Result, &'static str> { + schedule: &'a Schedule, + ) -> Result { use wasmi_validation::{validate_module, PlainValidator}; let module = @@ -290,9 +290,9 @@ impl<'a, Gas: 'a + From + UniqueSaturatedInto + Clone> ContractModule< /// - all imported functions from the external environment matches defined by `env` module, /// /// The preprocessing includes injecting code for gas metering and metering the height of stack. -pub fn prepare_contract( +pub fn prepare_contract( original_code: &[u8], - schedule: &Schedule, + schedule: &Schedule, ) -> Result { let mut contract_module = ContractModule::new(original_code, schedule)?; contract_module.scan_exports()?; @@ -347,7 +347,6 @@ pub fn prepare_contract( #[cfg(test)] mod tests { use super::*; - use crate::tests::Test; use crate::exec::Ext; use std::fmt; use wabt; @@ -377,8 +376,8 @@ mod tests { #[test] fn $name() { let wasm = wabt::Wat2Wasm::new().validate(false).convert($wat).unwrap(); - let schedule = Schedule::::default(); - let r = prepare_contract::(wasm.as_ref(), &schedule); + let schedule = Schedule::default(); + let r = prepare_contract::(wasm.as_ref(), &schedule); assert_matches!(r, $($expected)*); } }; @@ -406,7 +405,7 @@ mod tests { // Tests below assumes that maximum page number is configured to a certain number. #[test] fn assume_memory_size() { - assert_eq!(Schedule::::default().max_memory_pages, 16); + assert_eq!(Schedule::default().max_memory_pages, 16); } prepare_test!(memory_with_one_page, @@ -620,9 +619,9 @@ mod tests { ) "# ).unwrap(); - let mut schedule = Schedule::::default(); + let mut schedule = Schedule::default(); schedule.enable_println = true; - let r = prepare_contract::(wasm.as_ref(), &schedule); + let r = prepare_contract::(wasm.as_ref(), &schedule); assert_matches!(r, Ok(_)); } } diff --git a/substrate/srml/contracts/src/wasm/runtime.rs b/substrate/srml/contracts/src/wasm/runtime.rs index 8f7c10b407..479b296d81 100644 --- a/substrate/srml/contracts/src/wasm/runtime.rs +++ b/substrate/srml/contracts/src/wasm/runtime.rs @@ -21,13 +21,13 @@ use crate::exec::{ Ext, VmExecResult, OutputBuf, EmptyOutputBuf, CallReceipt, InstantiateReceipt, StorageKey, TopicOf, }; -use crate::gas::{GasMeter, Token, GasMeterResult, approx_gas_for_balance}; +use crate::gas::{Gas, GasMeter, Token, GasMeterResult, approx_gas_for_balance}; use sandbox; use system; use rstd::prelude::*; use rstd::mem; use parity_codec::{Decode, Encode}; -use runtime_primitives::traits::{CheckedMul, CheckedAdd, Bounded, SaturatedConversion}; +use runtime_primitives::traits::{Bounded, SaturatedConversion}; /// Enumerates all possible *special* trap conditions. /// @@ -45,7 +45,7 @@ pub(crate) struct Runtime<'a, E: Ext + 'a> { // we wrap output buffer to make it possible to take the buffer out. empty_output_buf: Option, scratch_buf: Vec, - schedule: &'a Schedule<::Gas>, + schedule: &'a Schedule, memory: sandbox::Memory, gas_meter: &'a mut GasMeter, special_trap: Option, @@ -55,7 +55,7 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> { ext: &'a mut E, input_data: Vec, empty_output_buf: EmptyOutputBuf, - schedule: &'a Schedule<::Gas>, + schedule: &'a Schedule, memory: sandbox::Memory, gas_meter: &'a mut GasMeter, ) -> Self { @@ -97,7 +97,7 @@ pub(crate) fn to_execution_result( #[cfg_attr(test, derive(Debug, PartialEq, Eq))] #[derive(Copy, Clone)] -pub enum RuntimeToken { +pub enum RuntimeToken { /// Explicit call to the `gas` function. Charge the gas meter /// with the value provided. Explicit(u32), @@ -115,39 +115,39 @@ pub enum RuntimeToken { DepositEvent(u32, u32), } -impl Token for RuntimeToken { - type Metadata = Schedule; +impl Token for RuntimeToken { + type Metadata = Schedule; - fn calculate_amount(&self, metadata: &Schedule) -> T::Gas { + fn calculate_amount(&self, metadata: &Schedule) -> Gas { use self::RuntimeToken::*; let value = match *self { Explicit(amount) => Some(amount.into()), ReadMemory(byte_count) => metadata .sandbox_data_read_cost - .checked_mul(&byte_count.into()), + .checked_mul(byte_count.into()), WriteMemory(byte_count) => metadata .sandbox_data_write_cost - .checked_mul(&byte_count.into()), + .checked_mul(byte_count.into()), ReturnData(byte_count) => metadata .return_data_per_byte_cost - .checked_mul(&byte_count.into()), + .checked_mul(byte_count.into()), DepositEvent(topic_count, data_byte_count) => { let data_cost = metadata .event_data_per_byte_cost - .checked_mul(&data_byte_count.into()); + .checked_mul(data_byte_count.into()); let topics_cost = metadata .event_per_topic_cost - .checked_mul(&topic_count.into()); + .checked_mul(topic_count.into()); data_cost .and_then(|data_cost| { topics_cost.and_then(|topics_cost| { - data_cost.checked_add(&topics_cost) + data_cost.checked_add(topics_cost) }) }) .and_then(|data_and_topics_cost| - data_and_topics_cost.checked_add(&metadata.event_base_cost) + data_and_topics_cost.checked_add(metadata.event_base_cost) ) }, ComputedDispatchFee(gas) => Some(gas), @@ -221,7 +221,7 @@ fn read_sandbox_memory_into_buf( /// - out of gas /// - designated area is not within the bounds of the sandbox memory. fn write_sandbox_memory( - schedule: &Schedule, + schedule: &Schedule, gas_meter: &mut GasMeter, memory: &sandbox::Memory, ptr: u32, @@ -509,7 +509,7 @@ define_env!(Env, , // Stores the amount of gas left into the scratch buffer. // - // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. + // The data is encoded as Gas. The current contents of the scratch buffer are overwritten. ext_gas_left(ctx) => { ctx.scratch_buf.clear(); ctx.gas_meter.gas_left().encode_to(&mut ctx.scratch_buf); @@ -573,7 +573,7 @@ define_env!(Env, , // Charge gas for dispatching this call. let fee = { let balance_fee = <::T as Trait>::ComputeDispatchFee::compute_dispatch_fee(&call); - approx_gas_for_balance::<::T>(ctx.gas_meter.gas_price(), balance_fee) + approx_gas_for_balance(ctx.gas_meter.gas_price(), balance_fee) }; charge_gas(&mut ctx.gas_meter, ctx.schedule, RuntimeToken::ComputedDispatchFee(fee))?;