Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion bin/node/executor/tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

use codec::{Encode, Decode, Joiner};
use frame_support::{
StorageMap,
traits::Currency,
weights::{GetDispatchInfo, DispatchInfo, DispatchClass},
};
Expand Down
2 changes: 1 addition & 1 deletion bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment, Currency
use pallet_session::{historical as pallet_session_historical};
use sp_inherents::{InherentData, CheckInherentsResult};
use static_assertions::const_assert;
use pallet_contracts::WeightInfo;
use pallet_contracts::weights::WeightInfo;

#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
Expand Down
1 change: 1 addition & 0 deletions frame/contracts/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ use parity_wasm::elements::{Instruction, ValueType, BlockType};
use sp_runtime::traits::{Hash, Bounded, Zero};
use sp_std::{default::Default, convert::{TryInto}, vec::Vec, vec};
use pallet_contracts_primitives::RentProjection;
use frame_support::weights::Weight;

/// How many batches we do per API benchmark.
const API_BENCHMARK_BATCHES: u32 = 20;
Expand Down
6 changes: 3 additions & 3 deletions frame/contracts/src/chain_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! A mechanism for runtime authors to augment the functionality of contracts.
//!
//! The runtime is able to call into any contract and retrieve the result using
//! [`bare_call`](crate::Module::bare_call). This already allows customization of runtime
//! [`bare_call`](crate::Pallet::bare_call). This already allows customization of runtime
//! behaviour by user generated code (contracts). However, often it is more straightforward
//! to allow the reverse behaviour: The contract calls into the runtime. We call the latter
//! one a "chain extension" because it allows the chain to extend the set of functions that are
Expand All @@ -37,7 +37,7 @@
//! [`charge_weight`](Environment::charge_weight) function must be called **before**
//! carrying out any action that causes the consumption of the chargeable weight.
//! It cannot be overstated how delicate of a process the creation of a chain extension
//! is. Check whether using [`bare_call`](crate::Module::bare_call) suffices for the
//! is. Check whether using [`bare_call`](crate::Pallet::bare_call) suffices for the
//! use case at hand.
//!
//! # Benchmarking
Expand Down Expand Up @@ -328,7 +328,7 @@ where
///
/// If the contract supplied buffer is smaller than the passed `buffer` an `Err` is returned.
/// If `allow_skip` is set to true the contract is allowed to skip the copying of the buffer
/// by supplying the guard value of [`u32::max_value()`] as `out_ptr`. The
/// by supplying the guard value of `u32::max_value()` as `out_ptr`. The
/// `weight_per_byte` is only charged when the write actually happens and is not skipped or
/// failed due to a too small output buffer.
pub fn write(
Expand Down
41 changes: 29 additions & 12 deletions frame/contracts/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// limitations under the License.

use crate::{
CodeHash, Event, RawEvent, Config, Module as Contracts,
CodeHash, Event, Config, Module as Contracts,
TrieId, BalanceOf, ContractInfo, gas::GasMeter, rent::Rent, storage::{self, Storage},
Error, ContractInfoOf, Schedule,
};
Expand All @@ -30,7 +30,7 @@ use frame_support::{
dispatch::{DispatchResult, DispatchError},
traits::{ExistenceRequirement, Currency, Time, Randomness, Get},
weights::Weight,
ensure, StorageMap,
ensure,
};
use pallet_contracts_primitives::{ErrorOrigin, ExecError, ExecReturnValue, ExecResult, ReturnFlags};

Expand All @@ -57,7 +57,11 @@ pub enum TransactorKind {
///
/// This interface is specialized to an account of the executing code, so all
/// operations are implicitly performed on that account.
pub trait Ext {
///
/// # Note
///
/// This trait is sealed and cannot be implemented by downstream crates.
pub trait Ext: sealing::Sealed {
type T: Config;

/// Returns the storage entry of the executing account by the given `key`.
Expand Down Expand Up @@ -446,7 +450,7 @@ where
.ok_or(Error::<T>::NewContractNotFunded)?;

// Deposit an instantiation event.
deposit_event::<T>(vec![], RawEvent::Instantiated(caller.clone(), dest.clone()));
deposit_event::<T>(vec![], Event::Instantiated(caller.clone(), dest.clone()));

Ok(output)
});
Expand Down Expand Up @@ -664,7 +668,7 @@ where
if let Some(ContractInfo::Alive(info)) = ContractInfoOf::<T>::take(&self_id) {
Storage::<T>::queue_trie_for_deletion(&info).map_err(|e| (e, 0))?;
let code_len = E::remove_user(info.code_hash);
Contracts::<T>::deposit_event(RawEvent::Terminated(self_id, beneficiary.clone()));
Contracts::<T>::deposit_event(Event::Terminated(self_id, beneficiary.clone()));
Ok(code_len)
} else {
panic!(
Expand Down Expand Up @@ -708,7 +712,7 @@ where
if let Ok(_) = result {
deposit_event::<Self::T>(
vec![],
RawEvent::Restored(
Event::Restored(
self.ctx.self_account.clone(),
dest,
code_hash,
Expand Down Expand Up @@ -754,7 +758,7 @@ where
fn deposit_event(&mut self, topics: Vec<T::Hash>, data: Vec<u8>) {
deposit_event::<Self::T>(
topics,
RawEvent::ContractEmitted(self.ctx.self_account.clone(), data)
Event::ContractEmitted(self.ctx.self_account.clone(), data)
);
}

Expand Down Expand Up @@ -799,6 +803,20 @@ fn deposit_event<T: Config>(
)
}

mod sealing {
use super::*;

pub trait Sealed {}

impl<'a, 'b: 'a, T: Config, E> Sealed for CallContext<'a, 'b, T, E> {}

#[cfg(test)]
impl Sealed for crate::wasm::MockExt {}

#[cfg(test)]
impl Sealed for &mut crate::wasm::MockExt {}
}

/// These tests exercise the executive layer.
///
/// In these tests the VM/loader are mocked. Instead of dealing with wasm bytecode they use simple closures.
Expand All @@ -809,21 +827,20 @@ mod tests {
use super::*;
use crate::{
gas::GasMeter, tests::{ExtBuilder, Test, Event as MetaEvent},
gas::Gas,
storage::Storage,
tests::{
ALICE, BOB, CHARLIE,
test_utils::{place_contract, set_balance, get_balance},
},
Error,
Error, Weight,
};
use sp_runtime::DispatchError;
use assert_matches::assert_matches;
use std::{cell::RefCell, collections::HashMap, rc::Rc};

type MockContext<'a> = ExecutionContext<'a, Test, MockExecutable>;

const GAS_LIMIT: Gas = 10_000_000_000;
const GAS_LIMIT: Weight = 10_000_000_000;

thread_local! {
static LOADER: RefCell<MockLoader> = RefCell::new(MockLoader::default());
Expand Down Expand Up @@ -1334,7 +1351,7 @@ mod tests {
// there are instantiation event.
assert_eq!(Storage::<Test>::code_hash(&instantiated_contract_address).unwrap(), dummy_ch);
assert_eq!(&events(), &[
RawEvent::Instantiated(ALICE, instantiated_contract_address)
Event::Instantiated(ALICE, instantiated_contract_address)
]);
});
}
Expand Down Expand Up @@ -1410,7 +1427,7 @@ mod tests {
// there are instantiation event.
assert_eq!(Storage::<Test>::code_hash(&instantiated_contract_address).unwrap(), dummy_ch);
assert_eq!(&events(), &[
RawEvent::Instantiated(BOB, instantiated_contract_address)
Event::Instantiated(BOB, instantiated_contract_address)
]);
});
}
Expand Down
96 changes: 46 additions & 50 deletions frame/contracts/src/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,11 @@ use sp_core::crypto::UncheckedFrom;
#[cfg(test)]
use std::{any::Any, fmt::Debug};

// Gas is essentially the same as weight. It is a 1 to 1 correspondence.
pub type Gas = Weight;

#[derive(Debug, PartialEq, Eq)]
pub struct ChargedAmount(Gas);
pub struct ChargedAmount(Weight);

impl ChargedAmount {
pub fn amount(&self) -> Gas {
pub fn amount(&self) -> Weight {
self.0
}
}
Expand Down Expand Up @@ -72,7 +69,7 @@ pub trait Token<T: Config>: 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) -> Gas;
fn calculate_amount(&self, metadata: &Self::Metadata) -> Weight;
}

/// A wrapper around a type-erased trait object of what used to be a `Token`.
Expand All @@ -83,9 +80,9 @@ pub struct ErasedToken {
}

pub struct GasMeter<T: Config> {
gas_limit: Gas,
gas_limit: Weight,
/// Amount of gas left from initial gas limit. Can reach zero.
gas_left: Gas,
gas_left: Weight,
_phantom: PhantomData<T>,
#[cfg(test)]
tokens: Vec<ErasedToken>,
Expand All @@ -95,7 +92,7 @@ impl<T: Config> GasMeter<T>
where
T::AccountId: UncheckedFrom<<T as frame_system::Config>::Hash> + AsRef<[u8]>
{
pub fn new(gas_limit: Gas) -> Self {
pub fn new(gas_limit: Weight) -> Self {
GasMeter {
gas_limit,
gas_left: gas_limit,
Expand Down Expand Up @@ -177,7 +174,7 @@ where
/// All unused gas in the nested gas meter is returned to this gas meter.
pub fn with_nested<R, F: FnOnce(Option<&mut GasMeter<T>>) -> R>(
&mut self,
amount: Gas,
amount: Weight,
f: F,
) -> R {
// NOTE that it is ok to allocate all available gas since it still ensured
Expand All @@ -197,12 +194,12 @@ where
}

/// Returns how much gas was used.
pub fn gas_spent(&self) -> Gas {
pub fn gas_spent(&self) -> Weight {
self.gas_limit - self.gas_left
}

/// Returns how much gas left from the initial budget.
pub fn gas_left(&self) -> Gas {
pub fn gas_left(&self) -> Weight {
self.gas_left
}

Expand Down Expand Up @@ -230,49 +227,48 @@ where
}
}

/// A simple utility macro that helps to match against a
/// list of tokens.
#[macro_export]
macro_rules! match_tokens {
($tokens_iter:ident,) => {
};
($tokens_iter:ident, $x:expr, $($rest:tt)*) => {
{
let next = ($tokens_iter).next().unwrap();
let pattern = $x;

// Note that we don't specify the type name directly in this macro,
// we only have some expression $x of some type. At the same time, we
// have an iterator of Box<dyn Any> and to downcast we need to specify
// the type which we want downcast to.
//
// So what we do is we assign `_pattern_typed_next_ref` to a variable which has
// the required type.
//
// Then we make `_pattern_typed_next_ref = token.downcast_ref()`. This makes
// rustc infer the type `T` (in `downcast_ref<T: Any>`) to be the same as in $x.

let mut _pattern_typed_next_ref = &pattern;
_pattern_typed_next_ref = match next.token.downcast_ref() {
Some(p) => {
assert_eq!(p, &pattern);
p
}
None => {
panic!("expected type {} got {}", stringify!($x), next.description);
}
};
}

match_tokens!($tokens_iter, $($rest)*);
};
}

#[cfg(test)]
mod tests {
use super::{GasMeter, Token};
use crate::tests::Test;

/// A simple utility macro that helps to match against a
/// list of tokens.
macro_rules! match_tokens {
($tokens_iter:ident,) => {
};
($tokens_iter:ident, $x:expr, $($rest:tt)*) => {
{
let next = ($tokens_iter).next().unwrap();
let pattern = $x;

// Note that we don't specify the type name directly in this macro,
// we only have some expression $x of some type. At the same time, we
// have an iterator of Box<dyn Any> and to downcast we need to specify
// the type which we want downcast to.
//
// So what we do is we assign `_pattern_typed_next_ref` to a variable which has
// the required type.
//
// Then we make `_pattern_typed_next_ref = token.downcast_ref()`. This makes
// rustc infer the type `T` (in `downcast_ref<T: Any>`) to be the same as in $x.

let mut _pattern_typed_next_ref = &pattern;
_pattern_typed_next_ref = match next.token.downcast_ref() {
Some(p) => {
assert_eq!(p, &pattern);
p
}
None => {
panic!("expected type {} got {}", stringify!($x), next.description);
}
};
}

match_tokens!($tokens_iter, $($rest)*);
};
}

/// A trivial token that charges the specified number of gas units.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
struct SimpleToken(u64);
Expand Down
Loading