Rename more things related to contract instantiation (#3664)

* Rename more things related to contract instantiation

* rename `creator_ch`

* Fix node runtime

* fix contracts tests

* Little fix
This commit is contained in:
Ashley
2019-09-23 21:32:44 +12:00
committed by Sergei Pepyakin
parent e0b3564f2d
commit 0a469666c1
8 changed files with 117 additions and 114 deletions
+2 -2
View File
@@ -84,7 +84,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// and set impl_version to equal spec_version. If only runtime // and set impl_version to equal spec_version. If only runtime
// implementation changes and behavior does not, then leave spec_version as // implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version. // is and increment impl_version.
spec_version: 160, spec_version: 161,
impl_version: 161, impl_version: 161,
apis: RUNTIME_API_VERSIONS, apis: RUNTIME_API_VERSIONS,
}; };
@@ -409,7 +409,7 @@ impl contracts::Trait for Runtime {
type TransactionByteFee = ContractTransactionByteFee; type TransactionByteFee = ContractTransactionByteFee;
type ContractFee = ContractFee; type ContractFee = ContractFee;
type CallBaseFee = contracts::DefaultCallBaseFee; type CallBaseFee = contracts::DefaultCallBaseFee;
type CreateBaseFee = contracts::DefaultCreateBaseFee; type InstantiateBaseFee = contracts::DefaultInstantiateBaseFee;
type MaxDepth = contracts::DefaultMaxDepth; type MaxDepth = contracts::DefaultMaxDepth;
type MaxValueSize = contracts::DefaultMaxValueSize; type MaxValueSize = contracts::DefaultMaxValueSize;
type BlockGasLimit = contracts::DefaultBlockGasLimit; type BlockGasLimit = contracts::DefaultBlockGasLimit;
+5 -5
View File
@@ -123,7 +123,7 @@ While these functions only modify the local `Map`, if changes made by them are c
**complexity**: Each lookup has a logarithmical computing time to the number of already inserted entries. No additional memory is required. **complexity**: Each lookup has a logarithmical computing time to the number of already inserted entries. No additional memory is required.
## create_contract ## instantiate_contract
Calls `contract_exists` and if it doesn't exist, do not modify the local `Map` similarly to `set_rent_allowance`. Calls `contract_exists` and if it doesn't exist, do not modify the local `Map` similarly to `set_rent_allowance`.
@@ -174,7 +174,7 @@ Assuming marshaled size of a balance value is of the constant size we can neglec
## Initialization ## Initialization
Before a call or create can be performed the execution context must be initialized. Before a call or instantiate can be performed the execution context must be initialized.
For the first call or instantiation in the handling of an extrinsic, this involves two calls: For the first call or instantiation in the handling of an extrinsic, this involves two calls:
@@ -213,7 +213,7 @@ and on top of that at most once per block:
- `kill_child_storage` - `kill_child_storage`
- mutation of `ContractInfoOf` - mutation of `ContractInfoOf`
Loading code most likely will trigger a DB read, since the code is immutable and therefore will not get into the cache (unless a suicide removes it, or it has been created in the same call chain). Loading code most likely will trigger a DB read, since the code is immutable and therefore will not get into the cache (unless a suicide removes it, or it has been instantiated in the same call chain).
Also, `transfer` can make up to 2 DB reads and up to 2 DB writes (if flushed to the storage) in the standard case. If removal of the source account takes place then it will additionally perform a DB write per one storage entry that the account has. Also, `transfer` can make up to 2 DB reads and up to 2 DB writes (if flushed to the storage) in the standard case. If removal of the source account takes place then it will additionally perform a DB write per one storage entry that the account has.
@@ -229,9 +229,9 @@ This function takes the code of the constructor and input data. Instantiation of
1. Initialization of the execution context. 1. Initialization of the execution context.
2. Calling `DetermineContractAddress` hook to determine an address for the contract, 2. Calling `DetermineContractAddress` hook to determine an address for the contract,
3. `transfer`-ing funds between self and the newly created contract. 3. `transfer`-ing funds between self and the newly instantiated contract.
4. Executing the constructor code. This will yield the final code of the code. 4. Executing the constructor code. This will yield the final code of the code.
5. Storing the code for the newly created contract in the overlay. 5. Storing the code for the newly instantiated contract in the overlay.
6. Committing overlayed changed to the underlying `AccountDb`. 6. Committing overlayed changed to the underlying `AccountDb`.
**Note** that the complexity of executing the constructor code should be considered separately. **Note** that the complexity of executing the constructor code should be considered separately.
+4 -4
View File
@@ -37,7 +37,7 @@ pub struct ChangeEntry<T: Trait> {
/// If Some(_), then the account balance is modified to the value. If None and `reset` is false, /// If Some(_), then the account balance is modified to the value. If None and `reset` is false,
/// the balance unmodified. If None and `reset` is true, the balance is reset to 0. /// the balance unmodified. If None and `reset` is true, the balance is reset to 0.
balance: Option<BalanceOf<T>>, balance: Option<BalanceOf<T>>,
/// If Some(_), then a contract is created with the code hash. If None and `reset` is false, /// If Some(_), then a contract is instantiated with the code hash. If None and `reset` is false,
/// then the contract code is unmodified. If None and `reset` is true, the contract is deleted. /// then the contract code is unmodified. If None and `reset` is true, the contract is deleted.
code_hash: Option<CodeHash<T>>, code_hash: Option<CodeHash<T>>,
/// If Some(_), then the rent allowance is set to the value. If None and `reset` is false, then /// If Some(_), then the rent allowance is set to the value. If None and `reset` is false, then
@@ -189,7 +189,7 @@ impl<T: Trait> AccountDb<T> for DirectAccountDb {
last_write: None, last_write: None,
} }
} }
// New contract is being created. // New contract is being instantiated.
(_, None, Some(code_hash)) => { (_, None, Some(code_hash)) => {
AliveContractInfo::<T> { AliveContractInfo::<T> {
code_hash, code_hash,
@@ -200,7 +200,7 @@ impl<T: Trait> AccountDb<T> for DirectAccountDb {
last_write: None, last_write: None,
} }
} }
// There is no existing at the address nor a new one to be created. // There is no existing at the address nor a new one to be instantiated.
(_, None, None) => continue, (_, None, None) => continue,
}; };
@@ -278,7 +278,7 @@ impl<'a, T: Trait> OverlayAccountDb<'a, T> {
} }
/// Return an error if contract already exists (either if it is alive or tombstone) /// Return an error if contract already exists (either if it is alive or tombstone)
pub fn create_contract( pub fn instantiate_contract(
&mut self, &mut self,
account: &T::AccountId, account: &T::AccountId,
code_hash: CodeHash<T>, code_hash: CodeHash<T>,
+34 -34
View File
@@ -421,7 +421,7 @@ where
) -> Result<(T::AccountId, ExecReturnValue), ExecError> { ) -> Result<(T::AccountId, ExecReturnValue), ExecError> {
if self.depth == self.config.max_depth as usize { if self.depth == self.config.max_depth as usize {
return Err(ExecError { return Err(ExecError {
reason: "reached maximum depth, cannot create", reason: "reached maximum depth, cannot instantiate",
buffer: input_data, buffer: input_data,
}); });
} }
@@ -448,7 +448,7 @@ where
let output = self.with_nested_context(dest.clone(), dest_trie_id, |nested| { let output = self.with_nested_context(dest.clone(), dest_trie_id, |nested| {
try_or_exec_error!( try_or_exec_error!(
nested.overlay.create_contract(&dest, code_hash.clone()), nested.overlay.instantiate_contract(&dest, code_hash.clone()),
input_data input_data
); );
@@ -941,7 +941,7 @@ mod tests {
with_externalities(&mut ExtBuilder::default().build(), || { with_externalities(&mut ExtBuilder::default().build(), || {
let cfg = Config::preload(); let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.create_contract(&BOB, exec_ch).unwrap(); ctx.overlay.instantiate_contract(&BOB, exec_ch).unwrap();
assert_matches!( assert_matches!(
ctx.call(BOB, value, &mut gas_meter, data), ctx.call(BOB, value, &mut gas_meter, data),
@@ -1041,7 +1041,7 @@ mod tests {
with_externalities(&mut ExtBuilder::default().build(), || { with_externalities(&mut ExtBuilder::default().build(), || {
let cfg = Config::preload(); let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.create_contract(&BOB, return_ch).unwrap(); ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap();
ctx.overlay.set_balance(&origin, 100); ctx.overlay.set_balance(&origin, 100);
ctx.overlay.set_balance(&dest, 0); ctx.overlay.set_balance(&dest, 0);
@@ -1064,7 +1064,7 @@ mod tests {
let dest = BOB; let dest = BOB;
// This test sends 50 units of currency to a non-existent account. // This test sends 50 units of currency to a non-existent account.
// This should create lead to creation of a new account thus // This should lead to creation of a new account thus
// a fee should be charged. // a fee should be charged.
with_externalities( with_externalities(
&mut ExtBuilder::default().existential_deposit(15).build(), &mut ExtBuilder::default().existential_deposit(15).build(),
@@ -1123,7 +1123,7 @@ mod tests {
); );
// This test sends 50 units of currency as an endownment to a newly // This test sends 50 units of currency as an endownment to a newly
// created contract. // instantiated contract.
with_externalities( with_externalities(
&mut ExtBuilder::default().existential_deposit(15).build(), &mut ExtBuilder::default().existential_deposit(15).build(),
|| { || {
@@ -1202,7 +1202,7 @@ mod tests {
with_externalities(&mut ExtBuilder::default().build(), || { with_externalities(&mut ExtBuilder::default().build(), || {
let cfg = Config::preload(); let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.create_contract(&BOB, return_ch).unwrap(); ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap();
let result = ctx.call( let result = ctx.call(
dest, dest,
@@ -1233,7 +1233,7 @@ mod tests {
with_externalities(&mut ExtBuilder::default().build(), || { with_externalities(&mut ExtBuilder::default().build(), || {
let cfg = Config::preload(); let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.create_contract(&BOB, return_ch).unwrap(); ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap();
let result = ctx.call( let result = ctx.call(
dest, dest,
@@ -1261,7 +1261,7 @@ mod tests {
with_externalities(&mut ExtBuilder::default().build(), || { with_externalities(&mut ExtBuilder::default().build(), || {
let cfg = Config::preload(); let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.create_contract(&BOB, input_data_ch).unwrap(); ctx.overlay.instantiate_contract(&BOB, input_data_ch).unwrap();
let result = ctx.call( let result = ctx.call(
BOB, BOB,
@@ -1330,7 +1330,7 @@ mod tests {
with_externalities(&mut ExtBuilder::default().build(), || { with_externalities(&mut ExtBuilder::default().build(), || {
let cfg = Config::preload(); let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.create_contract(&BOB, recurse_ch).unwrap(); ctx.overlay.instantiate_contract(&BOB, recurse_ch).unwrap();
let result = ctx.call( let result = ctx.call(
BOB, BOB,
@@ -1375,8 +1375,8 @@ mod tests {
let cfg = Config::preload(); let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader);
ctx.overlay.create_contract(&dest, bob_ch).unwrap(); ctx.overlay.instantiate_contract(&dest, bob_ch).unwrap();
ctx.overlay.create_contract(&CHARLIE, charlie_ch).unwrap(); ctx.overlay.instantiate_contract(&CHARLIE, charlie_ch).unwrap();
let result = ctx.call( let result = ctx.call(
dest, dest,
@@ -1416,8 +1416,8 @@ mod tests {
with_externalities(&mut ExtBuilder::default().build(), || { with_externalities(&mut ExtBuilder::default().build(), || {
let cfg = Config::preload(); let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.create_contract(&BOB, bob_ch).unwrap(); ctx.overlay.instantiate_contract(&BOB, bob_ch).unwrap();
ctx.overlay.create_contract(&CHARLIE, charlie_ch).unwrap(); ctx.overlay.instantiate_contract(&CHARLIE, charlie_ch).unwrap();
let result = ctx.call( let result = ctx.call(
BOB, BOB,
@@ -1472,7 +1472,7 @@ mod tests {
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000); ctx.overlay.set_balance(&ALICE, 1000);
let created_contract_address = assert_matches!( let instantiated_contract_address = assert_matches!(
ctx.instantiate( ctx.instantiate(
100, 100,
&mut GasMeter::<Test>::with_limit(10000, 1), &mut GasMeter::<Test>::with_limit(10000, 1),
@@ -1484,14 +1484,14 @@ mod tests {
// Check that the newly created account has the expected code hash and // Check that the newly created account has the expected code hash and
// there are instantiation event. // there are instantiation event.
assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch); assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch);
assert_eq!(&ctx.events(), &[ assert_eq!(&ctx.events(), &[
DeferredAction::DepositEvent { DeferredAction::DepositEvent {
event: RawEvent::Transfer(ALICE, created_contract_address, 100), event: RawEvent::Transfer(ALICE, instantiated_contract_address, 100),
topics: Vec::new(), topics: Vec::new(),
}, },
DeferredAction::DepositEvent { DeferredAction::DepositEvent {
event: RawEvent::Instantiated(ALICE, created_contract_address), event: RawEvent::Instantiated(ALICE, instantiated_contract_address),
topics: Vec::new(), topics: Vec::new(),
} }
]); ]);
@@ -1515,7 +1515,7 @@ mod tests {
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000); ctx.overlay.set_balance(&ALICE, 1000);
let created_contract_address = assert_matches!( let instantiated_contract_address = assert_matches!(
ctx.instantiate( ctx.instantiate(
100, 100,
&mut GasMeter::<Test>::with_limit(10000, 1), &mut GasMeter::<Test>::with_limit(10000, 1),
@@ -1526,7 +1526,7 @@ mod tests {
); );
// Check that the account has not been created. // Check that the account has not been created.
assert!(ctx.overlay.get_code_hash(&created_contract_address).is_none()); assert!(ctx.overlay.get_code_hash(&instantiated_contract_address).is_none());
assert!(ctx.events().is_empty()); assert!(ctx.events().is_empty());
} }
); );
@@ -1538,12 +1538,12 @@ mod tests {
let mut loader = MockLoader::empty(); let mut loader = MockLoader::empty();
let dummy_ch = loader.insert(|_| exec_success()); let dummy_ch = loader.insert(|_| exec_success());
let created_contract_address = Rc::new(RefCell::new(None::<u64>)); let instantiated_contract_address = Rc::new(RefCell::new(None::<u64>));
let creator_ch = loader.insert({ let instantiator_ch = loader.insert({
let dummy_ch = dummy_ch.clone(); let dummy_ch = dummy_ch.clone();
let created_contract_address = Rc::clone(&created_contract_address); let instantiated_contract_address = Rc::clone(&instantiated_contract_address);
move |ctx| { move |ctx| {
// Instantiate a contract and save it's address in `created_contract_address`. // Instantiate a contract and save it's address in `instantiated_contract_address`.
let (address, output) = ctx.ext.instantiate( let (address, output) = ctx.ext.instantiate(
&dummy_ch, &dummy_ch,
15u64, 15u64,
@@ -1551,7 +1551,7 @@ mod tests {
vec![] vec![]
).unwrap(); ).unwrap();
*created_contract_address.borrow_mut() = address.into(); *instantiated_contract_address.borrow_mut() = address.into();
Ok(output) Ok(output)
} }
}); });
@@ -1562,29 +1562,29 @@ mod tests {
let cfg = Config::preload(); let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000); ctx.overlay.set_balance(&ALICE, 1000);
ctx.overlay.create_contract(&BOB, creator_ch).unwrap(); ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap();
assert_matches!( assert_matches!(
ctx.call(BOB, 20, &mut GasMeter::<Test>::with_limit(1000, 1), vec![]), ctx.call(BOB, 20, &mut GasMeter::<Test>::with_limit(1000, 1), vec![]),
Ok(_) Ok(_)
); );
let created_contract_address = created_contract_address.borrow().as_ref().unwrap().clone(); let instantiated_contract_address = instantiated_contract_address.borrow().as_ref().unwrap().clone();
// Check that the newly created account has the expected code hash and // Check that the newly created account has the expected code hash and
// there are instantiation event. // there are instantiation event.
assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch); assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch);
assert_eq!(&ctx.events(), &[ assert_eq!(&ctx.events(), &[
DeferredAction::DepositEvent { DeferredAction::DepositEvent {
event: RawEvent::Transfer(ALICE, BOB, 20), event: RawEvent::Transfer(ALICE, BOB, 20),
topics: Vec::new(), topics: Vec::new(),
}, },
DeferredAction::DepositEvent { DeferredAction::DepositEvent {
event: RawEvent::Transfer(BOB, created_contract_address, 15), event: RawEvent::Transfer(BOB, instantiated_contract_address, 15),
topics: Vec::new(), topics: Vec::new(),
}, },
DeferredAction::DepositEvent { DeferredAction::DepositEvent {
event: RawEvent::Instantiated(BOB, created_contract_address), event: RawEvent::Instantiated(BOB, instantiated_contract_address),
topics: Vec::new(), topics: Vec::new(),
}, },
]); ]);
@@ -1600,10 +1600,10 @@ mod tests {
let dummy_ch = loader.insert( let dummy_ch = loader.insert(
|_| Err(ExecError { reason: "It's a trap!", buffer: Vec::new() }) |_| Err(ExecError { reason: "It's a trap!", buffer: Vec::new() })
); );
let creator_ch = loader.insert({ let instantiator_ch = loader.insert({
let dummy_ch = dummy_ch.clone(); let dummy_ch = dummy_ch.clone();
move |ctx| { move |ctx| {
// Instantiate a contract and save it's address in `created_contract_address`. // Instantiate a contract and save it's address in `instantiated_contract_address`.
assert_matches!( assert_matches!(
ctx.ext.instantiate( ctx.ext.instantiate(
&dummy_ch, &dummy_ch,
@@ -1624,14 +1624,14 @@ mod tests {
let cfg = Config::preload(); let cfg = Config::preload();
let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader);
ctx.overlay.set_balance(&ALICE, 1000); ctx.overlay.set_balance(&ALICE, 1000);
ctx.overlay.create_contract(&BOB, creator_ch).unwrap(); ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap();
assert_matches!( assert_matches!(
ctx.call(BOB, 20, &mut GasMeter::<Test>::with_limit(1000, 1), vec![]), ctx.call(BOB, 20, &mut GasMeter::<Test>::with_limit(1000, 1), vec![]),
Ok(_) Ok(_)
); );
// The contract wasn't created so we don't expect to see an instantiation // The contract wasn't instantiated so we don't expect to see an instantiation
// event here. // event here.
assert_eq!(&ctx.events(), &[ assert_eq!(&ctx.events(), &[
DeferredAction::DepositEvent { DeferredAction::DepositEvent {
+38 -37
View File
@@ -25,14 +25,14 @@
//! //!
//! This module extends accounts based on the `Currency` trait to have smart-contract functionality. It can //! This module extends accounts based on the `Currency` trait to have smart-contract functionality. It can
//! be used with other modules that implement accounts based on `Currency`. These "smart-contract accounts" //! be used with other modules that implement accounts based on `Currency`. These "smart-contract accounts"
//! have the ability to create smart-contracts and make calls to other contract and non-contract accounts. //! have the ability to instantiate smart-contracts and make calls to other contract and non-contract accounts.
//! //!
//! The smart-contract code is stored once in a `code_cache`, and later retrievable via its `code_hash`. //! The smart-contract code is stored once in a `code_cache`, and later retrievable via its `code_hash`.
//! This means that multiple smart-contracts can be instantiated from the same `code_cache`, without replicating //! This means that multiple smart-contracts can be instantiated from the same `code_cache`, without replicating
//! the code each time. //! the code each time.
//! //!
//! When a smart-contract is called, its associated code is retrieved via the code hash and gets executed. //! When a smart-contract is called, its associated code is retrieved via the code hash and gets executed.
//! This call can alter the storage entries of the smart-contract account, create new smart-contracts, //! This call can alter the storage entries of the smart-contract account, instantiate new smart-contracts,
//! or call other smart-contracts. //! or call other smart-contracts.
//! //!
//! Finally, when an account is reaped, its associated code and storage of the smart-contract account //! Finally, when an account is reaped, its associated code and storage of the smart-contract account
@@ -60,7 +60,8 @@
//! //!
//! * `put_code` - Stores the given binary Wasm code into the chain's storage and returns its `code_hash`. //! * `put_code` - Stores the given binary Wasm code into the chain's storage and returns its `code_hash`.
//! * `instantiate` - Deploys a new contract from the given `code_hash`, optionally transferring some balance. //! * `instantiate` - Deploys a new contract from the given `code_hash`, optionally transferring some balance.
//! This creates a new smart contract account and calls its contract deploy handler to initialize the contract. //! This instantiates a new smart contract account and calls its contract deploy handler to
//! initialize the contract.
//! * `call` - Makes a call to an account, optionally transferring some balance. //! * `call` - Makes a call to an account, optionally transferring some balance.
//! //!
//! ### Signed Extensions //! ### Signed Extensions
@@ -74,8 +75,8 @@
//! //!
//! ## Usage //! ## Usage
//! //!
//! The Contract module is a work in progress. The following examples show how this Contract module can be //! The Contract module is a work in progress. The following examples show how this Contract module
//! used to create and call contracts. //! can be used to instantiate and call contracts.
//! //!
//! * [`ink`](https://github.com/paritytech/ink) is //! * [`ink`](https://github.com/paritytech/ink) is
//! an [`eDSL`](https://wiki.haskell.org/Embedded_domain_specific_language) that enables writing //! an [`eDSL`](https://wiki.haskell.org/Embedded_domain_specific_language) that enables writing
@@ -298,37 +299,37 @@ pub type NegativeImbalanceOf<T> =
<<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::NegativeImbalance; <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::NegativeImbalance;
parameter_types! { parameter_types! {
/// A resonable default value for [`Trait::SignedClaimedHandicap`]. /// A reasonable default value for [`Trait::SignedClaimedHandicap`].
pub const DefaultSignedClaimHandicap: u32 = 2; pub const DefaultSignedClaimHandicap: u32 = 2;
/// A resonable default value for [`Trait::TombstoneDeposit`]. /// A reasonable default value for [`Trait::TombstoneDeposit`].
pub const DefaultTombstoneDeposit: u32 = 16; pub const DefaultTombstoneDeposit: u32 = 16;
/// A resonable default value for [`Trait::StorageSizeOffset`]. /// A reasonable default value for [`Trait::StorageSizeOffset`].
pub const DefaultStorageSizeOffset: u32 = 8; pub const DefaultStorageSizeOffset: u32 = 8;
/// A resonable default value for [`Trait::RentByteFee`]. /// A reasonable default value for [`Trait::RentByteFee`].
pub const DefaultRentByteFee: u32 = 4; pub const DefaultRentByteFee: u32 = 4;
/// A resonable default value for [`Trait::RentDepositOffset`]. /// A reasonable default value for [`Trait::RentDepositOffset`].
pub const DefaultRentDepositOffset: u32 = 1000; pub const DefaultRentDepositOffset: u32 = 1000;
/// A resonable default value for [`Trait::SurchargeReward`]. /// A reasonable default value for [`Trait::SurchargeReward`].
pub const DefaultSurchargeReward: u32 = 150; pub const DefaultSurchargeReward: u32 = 150;
/// A resonable default value for [`Trait::TransferFee`]. /// A reasonable default value for [`Trait::TransferFee`].
pub const DefaultTransferFee: u32 = 0; pub const DefaultTransferFee: u32 = 0;
/// A resonable default value for [`Trait::CreationFee`]. /// A reasonable default value for [`Trait::InstantiationFee`].
pub const DefaultCreationFee: u32 = 0; pub const DefaultInstantiationFee: u32 = 0;
/// A resonable default value for [`Trait::TransactionBaseFee`]. /// A reasonable default value for [`Trait::TransactionBaseFee`].
pub const DefaultTransactionBaseFee: u32 = 0; pub const DefaultTransactionBaseFee: u32 = 0;
/// A resonable default value for [`Trait::TransactionByteFee`]. /// A reasonable default value for [`Trait::TransactionByteFee`].
pub const DefaultTransactionByteFee: u32 = 0; pub const DefaultTransactionByteFee: u32 = 0;
/// A resonable default value for [`Trait::ContractFee`]. /// A reasonable default value for [`Trait::ContractFee`].
pub const DefaultContractFee: u32 = 21; pub const DefaultContractFee: u32 = 21;
/// A resonable default value for [`Trait::CallBaseFee`]. /// A reasonable default value for [`Trait::CallBaseFee`].
pub const DefaultCallBaseFee: u32 = 1000; pub const DefaultCallBaseFee: u32 = 1000;
/// A resonable default value for [`Trait::CreateBaseFee`]. /// A reasonable default value for [`Trait::InstantiateBaseFee`].
pub const DefaultCreateBaseFee: u32 = 1000; pub const DefaultInstantiateBaseFee: u32 = 1000;
/// A resonable default value for [`Trait::MaxDepth`]. /// A reasonable default value for [`Trait::MaxDepth`].
pub const DefaultMaxDepth: u32 = 1024; pub const DefaultMaxDepth: u32 = 1024;
/// A resonable default value for [`Trait::MaxValueSize`]. /// A reasonable default value for [`Trait::MaxValueSize`].
pub const DefaultMaxValueSize: u32 = 16_384; pub const DefaultMaxValueSize: u32 = 16_384;
/// A resonable default value for [`Trait::BlockGasLimit`]. /// A reasonable default value for [`Trait::BlockGasLimit`].
pub const DefaultBlockGasLimit: u32 = 10_000_000; pub const DefaultBlockGasLimit: u32 = 10_000_000;
} }
@@ -341,13 +342,13 @@ pub trait Trait: timestamp::Trait {
/// The overarching event type. /// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>; type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
/// A function type to get the contract address given the creator. /// A function type to get the contract address given the instantiator.
type DetermineContractAddress: ContractAddressFor<CodeHash<Self>, Self::AccountId>; type DetermineContractAddress: ContractAddressFor<CodeHash<Self>, Self::AccountId>;
/// A function type that computes the fee for dispatching the given `Call`. /// A function type that computes the fee for dispatching the given `Call`.
/// ///
/// It is recommended (though not required) for this function to return a fee that would be taken /// It is recommended (though not required) for this function to return a fee that would be
/// by the Executive module for regular dispatch. /// taken by the Executive module for regular dispatch.
type ComputeDispatchFee: ComputeDispatchFee<<Self as Trait>::Call, BalanceOf<Self>>; type ComputeDispatchFee: ComputeDispatchFee<<Self as Trait>::Call, BalanceOf<Self>>;
/// trie id generator /// trie id generator
@@ -365,7 +366,7 @@ pub trait Trait: timestamp::Trait {
/// The minimum amount required to generate a tombstone. /// The minimum amount required to generate a tombstone.
type TombstoneDeposit: Get<BalanceOf<Self>>; type TombstoneDeposit: Get<BalanceOf<Self>>;
/// Size of a contract at the time of creation. This is a simple way to ensure /// Size of a contract at the time of instantiation. This is a simple way to ensure
/// that empty contracts eventually gets deleted. /// that empty contracts eventually gets deleted.
type StorageSizeOffset: Get<u32>; type StorageSizeOffset: Get<u32>;
@@ -397,16 +398,16 @@ pub trait Trait: timestamp::Trait {
/// The fee to be paid for making a transaction; the per-byte portion. /// The fee to be paid for making a transaction; the per-byte portion.
type TransactionByteFee: Get<BalanceOf<Self>>; type TransactionByteFee: Get<BalanceOf<Self>>;
/// The fee required to create a contract instance. /// The fee required to instantiate a contract instance.
type ContractFee: Get<BalanceOf<Self>>; type ContractFee: Get<BalanceOf<Self>>;
/// The base fee charged for calling into a contract. /// The base fee charged for calling into a contract.
type CallBaseFee: Get<Gas>; type CallBaseFee: Get<Gas>;
/// The base fee charged for creating a contract. /// The base fee charged for instantiating a contract.
type CreateBaseFee: Get<Gas>; type InstantiateBaseFee: Get<Gas>;
/// The maximum nesting level of a call/create stack. /// The maximum nesting level of a call/instantiate stack.
type MaxDepth: Get<u32>; type MaxDepth: Get<u32>;
/// The maximum size of a storage value in bytes. /// The maximum size of a storage value in bytes.
@@ -464,8 +465,8 @@ decl_module! {
/// The minimum amount required to generate a tombstone. /// The minimum amount required to generate a tombstone.
const TombstoneDeposit: BalanceOf<T> = T::TombstoneDeposit::get(); const TombstoneDeposit: BalanceOf<T> = T::TombstoneDeposit::get();
/// Size of a contract at the time of creation. This is a simple way to ensure /// Size of a contract at the time of instantiaion. This is a simple way to ensure that
/// that empty contracts eventually gets deleted. /// empty contracts eventually gets deleted.
const StorageSizeOffset: u32 = T::StorageSizeOffset::get(); const StorageSizeOffset: u32 = T::StorageSizeOffset::get();
/// Price of a byte of storage per one block interval. Should be greater than 0. /// Price of a byte of storage per one block interval. Should be greater than 0.
@@ -496,7 +497,7 @@ decl_module! {
/// The fee to be paid for making a transaction; the per-byte portion. /// The fee to be paid for making a transaction; the per-byte portion.
const TransactionByteFee: BalanceOf<T> = T::TransactionByteFee::get(); const TransactionByteFee: BalanceOf<T> = T::TransactionByteFee::get();
/// The fee required to create a contract instance. A reasonable default value /// The fee required to instantiate a contract instance. A reasonable default value
/// is 21. /// is 21.
const ContractFee: BalanceOf<T> = T::ContractFee::get(); const ContractFee: BalanceOf<T> = T::ContractFee::get();
@@ -504,11 +505,11 @@ decl_module! {
/// value is 135. /// value is 135.
const CallBaseFee: Gas = T::CallBaseFee::get(); const CallBaseFee: Gas = T::CallBaseFee::get();
/// The base fee charged for creating a contract. A reasonable default value /// The base fee charged for instantiating a contract. A reasonable default value
/// is 175. /// is 175.
const CreateBaseFee: Gas = T::CreateBaseFee::get(); const InstantiateBaseFee: Gas = T::InstantiateBaseFee::get();
/// The maximum nesting level of a call/create stack. A reasonable default /// The maximum nesting level of a call/instantiate stack. A reasonable default
/// value is 100. /// value is 100.
const MaxDepth: u32 = T::MaxDepth::get(); const MaxDepth: u32 = T::MaxDepth::get();
+11 -11
View File
@@ -69,7 +69,7 @@ impl_outer_dispatch! {
thread_local! { thread_local! {
static EXISTENTIAL_DEPOSIT: RefCell<u64> = RefCell::new(0); static EXISTENTIAL_DEPOSIT: RefCell<u64> = RefCell::new(0);
static TRANSFER_FEE: RefCell<u64> = RefCell::new(0); static TRANSFER_FEE: RefCell<u64> = RefCell::new(0);
static CREATION_FEE: RefCell<u64> = RefCell::new(0); static INSTANTIATION_FEE: RefCell<u64> = RefCell::new(0);
static BLOCK_GAS_LIMIT: RefCell<u64> = RefCell::new(0); static BLOCK_GAS_LIMIT: RefCell<u64> = RefCell::new(0);
} }
@@ -85,7 +85,7 @@ impl Get<u64> for TransferFee {
pub struct CreationFee; pub struct CreationFee;
impl Get<u64> for CreationFee { impl Get<u64> for CreationFee {
fn get() -> u64 { CREATION_FEE.with(|v| *v.borrow()) } fn get() -> u64 { INSTANTIATION_FEE.with(|v| *v.borrow()) }
} }
pub struct BlockGasLimit; pub struct BlockGasLimit;
@@ -155,7 +155,7 @@ parameter_types! {
pub const TransactionByteFee: u64 = 6; pub const TransactionByteFee: u64 = 6;
pub const ContractFee: u64 = 21; pub const ContractFee: u64 = 21;
pub const CallBaseFee: u64 = 135; pub const CallBaseFee: u64 = 135;
pub const CreateBaseFee: u64 = 175; pub const InstantiateBaseFee: u64 = 175;
pub const MaxDepth: u32 = 100; pub const MaxDepth: u32 = 100;
pub const MaxValueSize: u32 = 16_384; pub const MaxValueSize: u32 = 16_384;
} }
@@ -179,7 +179,7 @@ impl Trait for Test {
type TransactionByteFee = TransactionByteFee; type TransactionByteFee = TransactionByteFee;
type ContractFee = ContractFee; type ContractFee = ContractFee;
type CallBaseFee = CallBaseFee; type CallBaseFee = CallBaseFee;
type CreateBaseFee = CreateBaseFee; type InstantiateBaseFee = InstantiateBaseFee;
type MaxDepth = MaxDepth; type MaxDepth = MaxDepth;
type MaxValueSize = MaxValueSize; type MaxValueSize = MaxValueSize;
type BlockGasLimit = BlockGasLimit; type BlockGasLimit = BlockGasLimit;
@@ -233,7 +233,7 @@ pub struct ExtBuilder {
gas_price: u64, gas_price: u64,
block_gas_limit: u64, block_gas_limit: u64,
transfer_fee: u64, transfer_fee: u64,
creation_fee: u64, instantiation_fee: u64,
} }
impl Default for ExtBuilder { impl Default for ExtBuilder {
fn default() -> Self { fn default() -> Self {
@@ -242,7 +242,7 @@ impl Default for ExtBuilder {
gas_price: 2, gas_price: 2,
block_gas_limit: 100_000_000, block_gas_limit: 100_000_000,
transfer_fee: 0, transfer_fee: 0,
creation_fee: 0, instantiation_fee: 0,
} }
} }
} }
@@ -263,14 +263,14 @@ impl ExtBuilder {
self.transfer_fee = transfer_fee; self.transfer_fee = transfer_fee;
self self
} }
pub fn creation_fee(mut self, creation_fee: u64) -> Self { pub fn instantiation_fee(mut self, instantiation_fee: u64) -> Self {
self.creation_fee = creation_fee; self.instantiation_fee = instantiation_fee;
self self
} }
pub fn set_associated_consts(&self) { pub fn set_associated_consts(&self) {
EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit);
TRANSFER_FEE.with(|v| *v.borrow_mut() = self.transfer_fee); TRANSFER_FEE.with(|v| *v.borrow_mut() = self.transfer_fee);
CREATION_FEE.with(|v| *v.borrow_mut() = self.creation_fee); INSTANTIATION_FEE.with(|v| *v.borrow_mut() = self.instantiation_fee);
BLOCK_GAS_LIMIT.with(|v| *v.borrow_mut() = self.block_gas_limit); BLOCK_GAS_LIMIT.with(|v| *v.borrow_mut() = self.block_gas_limit);
} }
pub fn build(self) -> runtime_io::TestExternalities<Blake2Hasher> { pub fn build(self) -> runtime_io::TestExternalities<Blake2Hasher> {
@@ -651,7 +651,7 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() {
vec![], vec![],
)); ));
// Call the newly created contract. The contract is expected to dispatch a call // Call the newly instantiated contract. The contract is expected to dispatch a call
// and then trap. // and then trap.
assert_err!( assert_err!(
Contract::call( Contract::call(
@@ -1225,7 +1225,7 @@ const CODE_CHECK_DEFAULT_RENT_ALLOWANCE: &str = r#"
"#; "#;
#[test] #[test]
fn default_rent_allowance_on_create() { fn default_rent_allowance_on_instantiate() {
let (wasm, code_hash) = compile_module::<Test>(CODE_CHECK_DEFAULT_RENT_ALLOWANCE).unwrap(); let (wasm, code_hash) = compile_module::<Test>(CODE_CHECK_DEFAULT_RENT_ALLOWANCE).unwrap();
with_externalities( with_externalities(
+9 -9
View File
@@ -173,7 +173,7 @@ mod tests {
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
struct CreateEntry { struct InstantiateEntry {
code_hash: H256, code_hash: H256,
endowment: u64, endowment: u64,
data: Vec<u8>, data: Vec<u8>,
@@ -192,7 +192,7 @@ mod tests {
pub struct MockExt { pub struct MockExt {
storage: HashMap<StorageKey, Vec<u8>>, storage: HashMap<StorageKey, Vec<u8>>,
rent_allowance: u64, rent_allowance: u64,
creates: Vec<CreateEntry>, instantiates: Vec<InstantiateEntry>,
transfers: Vec<TransferEntry>, transfers: Vec<TransferEntry>,
dispatches: Vec<DispatchEntry>, dispatches: Vec<DispatchEntry>,
restores: Vec<RestoreEntry>, restores: Vec<RestoreEntry>,
@@ -220,7 +220,7 @@ mod tests {
gas_meter: &mut GasMeter<Test>, gas_meter: &mut GasMeter<Test>,
data: Vec<u8>, data: Vec<u8>,
) -> Result<(u64, ExecReturnValue), ExecError> { ) -> Result<(u64, ExecReturnValue), ExecError> {
self.creates.push(CreateEntry { self.instantiates.push(InstantiateEntry {
code_hash: code_hash.clone(), code_hash: code_hash.clone(),
endowment, endowment,
data: data.to_vec(), data: data.to_vec(),
@@ -476,7 +476,7 @@ mod tests {
); );
} }
const CODE_CREATE: &str = r#" const CODE_INSTANTIATE: &str = r#"
(module (module
;; ext_instantiate( ;; ext_instantiate(
;; code_ptr: u32, ;; code_ptr: u32,
@@ -507,7 +507,7 @@ mod tests {
;; Amount of value to transfer. ;; Amount of value to transfer.
;; Represented by u64 (8 bytes long) in little endian. ;; Represented by u64 (8 bytes long) in little endian.
(data (i32.const 4) "\03\00\00\00\00\00\00\00") (data (i32.const 4) "\03\00\00\00\00\00\00\00")
;; Input data to pass to the contract being created. ;; Input data to pass to the contract being instantiated.
(data (i32.const 12) "\01\02\03\04") (data (i32.const 12) "\01\02\03\04")
;; Hash of code. ;; Hash of code.
(data (i32.const 16) (data (i32.const 16)
@@ -518,18 +518,18 @@ mod tests {
"#; "#;
#[test] #[test]
fn contract_create() { fn contract_instantiate() {
let mut mock_ext = MockExt::default(); let mut mock_ext = MockExt::default();
let _ = execute( let _ = execute(
CODE_CREATE, CODE_INSTANTIATE,
vec![], vec![],
&mut mock_ext, &mut mock_ext,
&mut GasMeter::with_limit(50_000, 1), &mut GasMeter::with_limit(50_000, 1),
).unwrap(); ).unwrap();
assert_eq!( assert_eq!(
&mock_ext.creates, &mock_ext.instantiates,
&[CreateEntry { &[InstantiateEntry {
code_hash: [0x11; 32].into(), code_hash: [0x11; 32].into(),
endowment: 3, endowment: 3,
data: vec![1, 2, 3, 4], data: vec![1, 2, 3, 4],
+14 -12
View File
@@ -432,11 +432,12 @@ define_env!(Env, <E: Ext>,
// by the code hash. // by the code hash.
// //
// If the constructor runs to completion, then this returns the status code that the newly // If the constructor runs to completion, then this returns the status code that the newly
// created contract returns on exit in the bottom 8 bits of the return value. The top 24 bits // instantiated contract returns on exit in the bottom 8 bits of the return value. The top 24
// are 0s. A status code of 0 indicates success, and any other code indicates a failure. On // bits are 0s. A status code of 0 indicates success, and any other code indicates a failure.
// failure, any state changes made by the called contract are reverted and the contract is not // On failure, any state changes made by the called contract are reverted and the contract is
// instantiated. On a success status, the scratch buffer is filled with the encoded address of // not instantiated. On a success status, the scratch buffer is filled with the encoded address
// the newly created contract. In the case of a failure status, the scratch buffer is cleared. // of the newly instantiated contract. In the case of a failure status, the scratch buffer is
// cleared.
// //
// If the contract traps during execution or otherwise fails to complete successfully, then // If the contract traps during execution or otherwise fails to complete successfully, then
// this function clears the scratch buffer and returns 0x0100. As with a failure status, any // this function clears the scratch buffer and returns 0x0100. As with a failure status, any
@@ -445,8 +446,9 @@ define_env!(Env, <E: Ext>,
// This function creates an account and executes initializer code. After the execution, // This function creates an account and executes initializer code. After the execution,
// the returned buffer is saved as the code of the created account. // the returned buffer is saved as the code of the created account.
// //
// Returns 0 on the successful contract creation and puts the address of the created contract // Returns 0 on the successful contract instantiation and puts the address of the instantiated
// into the scratch buffer. Otherwise, returns non-zero value and clears the scratch buffer. // contract into the scratch buffer. Otherwise, returns non-zero value and clears the scratch
// buffer.
// //
// - code_hash_ptr: a pointer to the buffer that contains the initializer code. // - code_hash_ptr: a pointer to the buffer that contains the initializer code.
// - code_hash_len: length of the initializer code buffer. // - code_hash_len: length of the initializer code buffer.
@@ -535,9 +537,9 @@ define_env!(Env, <E: Ext>,
// Stores the address of the caller into the scratch buffer. // Stores the address of the caller into the scratch buffer.
// //
// If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the extrinsic // If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the
// will be returned. Otherwise, if this call is initiated by another contract then the address // extrinsic will be returned. Otherwise, if this call is initiated by another contract then the
// of the contract will be returned. // address of the contract will be returned.
ext_caller(ctx) => { ext_caller(ctx) => {
ctx.scratch_buf.clear(); ctx.scratch_buf.clear();
ctx.ext.caller().encode_to(&mut ctx.scratch_buf); ctx.ext.caller().encode_to(&mut ctx.scratch_buf);
@@ -717,8 +719,8 @@ define_env!(Env, <E: Ext>,
Ok(ctx.scratch_buf.len() as u32) Ok(ctx.scratch_buf.len() as u32)
}, },
// Copy data from the scratch buffer starting from `offset` with length `len` into the contract memory. // Copy data from the scratch buffer starting from `offset` with length `len` into the contract
// The region at which the data should be put is specified by `dest_ptr`. // memory. The region at which the data should be put is specified by `dest_ptr`.
// //
// In order to get size of the scratch buffer use `ext_scratch_size`. At the start of contract // In order to get size of the scratch buffer use `ext_scratch_size`. At the start of contract
// execution, the scratch buffer is filled with the input data. Whenever a contract calls // execution, the scratch buffer is filled with the input data. Whenever a contract calls