Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[env] pass salt argument to instantiate host function #599

Merged
merged 14 commits into from
Jan 19, 2021
Merged
7 changes: 4 additions & 3 deletions crates/env/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,15 +322,16 @@ where
/// - If the instantiation process runs out of gas.
/// - If given insufficient endowment.
/// - If the returned account ID failed to decode properly.
pub fn instantiate_contract<T, Args, C>(
params: &CreateParams<T, Args, C>,
pub fn instantiate_contract<T, Args, Salt, C>(
params: &CreateParams<T, Args, Salt, C>,
) -> Result<T::AccountId>
where
T: Environment,
Args: scale::Encode,
Salt: AsRef<[u8]>,
Robbepop marked this conversation as resolved.
Show resolved Hide resolved
{
<EnvInstance as OnInstance>::on_instance(|instance| {
TypedEnvBackend::instantiate_contract::<T, Args, C>(instance, params)
TypedEnvBackend::instantiate_contract::<T, Args, Salt, C>(instance, params)
})
}

Expand Down
7 changes: 4 additions & 3 deletions crates/env/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,14 @@ pub trait TypedEnvBackend: EnvBackend {
/// # Note
///
/// For more details visit: [`ink_env::instantiate_contract`]
fn instantiate_contract<T, Args, C>(
fn instantiate_contract<T, Args, Salt, C>(
&mut self,
params: &CreateParams<T, Args, C>,
params: &CreateParams<T, Args, Salt, C>,
) -> Result<T::AccountId>
where
T: Environment,
Args: scale::Encode;
Args: scale::Encode,
Salt: AsRef<[u8]>;
Robbepop marked this conversation as resolved.
Show resolved Hide resolved

/// Restores a smart contract tombstone.
///
Expand Down
100 changes: 79 additions & 21 deletions crates/env/src/call/create_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,15 @@ use crate::{
};
use core::marker::PhantomData;

/// Contracts that can be contructed from an `AccountId`.
pub mod state {
//! Type states that tell what state of a instantiation argument has not
//! yet been set properly for a valid construction.

/// Type state for the salt used for contract instantiation.
pub struct Salt;
ascjones marked this conversation as resolved.
Show resolved Hide resolved
}

/// Contracts that can be constructed from an `AccountId`.
///
/// # Note
///
Expand All @@ -44,7 +52,7 @@ where

/// Builds up contract instantiations.
#[derive(Debug)]
pub struct CreateParams<E, Args, R>
pub struct CreateParams<E, Args, Salt, R>
where
E: Environment,
{
Expand All @@ -54,8 +62,10 @@ where
gas_limit: u64,
/// The endowment for the instantiated contract.
endowment: E::Balance,
/// The input data for the instantation.
/// The input data for the instantiation.
exec_input: ExecutionInput<Args>,
/// The salt for determining the hash for the contract account ID.
salt_bytes: Salt,
/// The type of the instantiated contract.
return_type: ReturnType<R>,
}
Expand All @@ -66,9 +76,10 @@ where
// off-chain environment compilation.
all(not(feature = "std"), target_arch = "wasm32")
)]
impl<E, Args, R> CreateParams<E, Args, R>
impl<E, Args, Salt, R> CreateParams<E, Args, Salt, R>
where
E: Environment,
Salt: AsRef<[u8]>,
{
/// The code hash of the contract.
#[inline]
Expand All @@ -93,12 +104,19 @@ where
pub(crate) fn exec_input(&self) -> &ExecutionInput<Args> {
&self.exec_input
}

/// The salt for determining the hash for the contract account ID.
#[inline]
pub(crate) fn salt_bytes(&self) -> &Salt {
&self.salt_bytes
}
ascjones marked this conversation as resolved.
Show resolved Hide resolved
}

impl<E, Args, R> CreateParams<E, Args, R>
impl<E, Args, Salt, R> CreateParams<E, Args, Salt, R>
where
E: Environment,
Args: scale::Encode,
Salt: AsRef<[u8]>,
R: FromAccountId<E>,
{
/// Instantiates the contract and returns its account ID back to the caller.
Expand All @@ -109,7 +127,7 @@ where
}

/// Builds up contract instantiations.
pub struct CreateBuilder<E, CodeHash, GasLimit, Endowment, Args, R>
pub struct CreateBuilder<E, CodeHash, GasLimit, Endowment, Args, Salt, R>
where
E: Environment,
{
Expand All @@ -118,6 +136,7 @@ where
gas_limit: GasLimit,
endowment: Endowment,
exec_input: Args,
salt: Salt,
return_type: ReturnType<R>,
}

Expand Down Expand Up @@ -145,11 +164,12 @@ where
/// # };
/// # type Hash = <DefaultEnvironment as Environment>::Hash;
/// # type AccountId = <DefaultEnvironment as Environment>::AccountId;
/// # type Salt = &'static [u8];
/// # struct MyContract;
/// # impl FromAccountId<DefaultEnvironment> for MyContract {
/// # fn from_account_id(account_id: AccountId) -> Self { Self }
/// # }
/// let my_contract: MyContract = build_create::<DefaultEnvironment, MyContract>()
/// let my_contract: MyContract = build_create::<DefaultEnvironment, Salt, MyContract>()
/// .code_hash(Hash::from([0x42; 32]))
/// .gas_limit(4000)
/// .endowment(25)
Expand All @@ -159,6 +179,7 @@ where
/// .push_arg(true)
/// .push_arg(&[0x10u8; 32])
/// )
/// .salt_bytes(&[0xDE, 0xAD, 0xBE, 0xEF])
/// .params()
/// .instantiate()
/// .unwrap();
Expand All @@ -174,6 +195,7 @@ pub fn build_create<E, R>() -> CreateBuilder<
Unset<u64>,
Unset<E::Balance>,
Unset<ExecutionInput<EmptyArgumentList>>,
Unset<state::Salt>,
R,
>
where
Expand All @@ -186,12 +208,13 @@ where
gas_limit: Default::default(),
endowment: Default::default(),
exec_input: Default::default(),
salt: Default::default(),
return_type: Default::default(),
}
}

impl<E, GasLimit, Endowment, Args, R>
CreateBuilder<E, Unset<E::Hash>, GasLimit, Endowment, Args, R>
impl<E, GasLimit, Endowment, Args, Salt, R>
CreateBuilder<E, Unset<E::Hash>, GasLimit, Endowment, Args, Salt, R>
where
E: Environment,
{
Expand All @@ -200,20 +223,21 @@ where
pub fn code_hash(
self,
code_hash: E::Hash,
) -> CreateBuilder<E, Set<E::Hash>, GasLimit, Endowment, Args, R> {
) -> CreateBuilder<E, Set<E::Hash>, GasLimit, Endowment, Args, Salt, R> {
CreateBuilder {
env: Default::default(),
code_hash: Set(code_hash),
gas_limit: self.gas_limit,
endowment: self.endowment,
exec_input: self.exec_input,
salt: self.salt,
return_type: self.return_type,
}
}
}

impl<E, CodeHash, Endowment, Args, R>
CreateBuilder<E, CodeHash, Unset<u64>, Endowment, Args, R>
impl<E, CodeHash, Endowment, Args, Salt, R>
CreateBuilder<E, CodeHash, Unset<u64>, Endowment, Args, Salt, R>
where
E: Environment,
{
Expand All @@ -222,20 +246,21 @@ where
pub fn gas_limit(
self,
gas_limit: u64,
) -> CreateBuilder<E, CodeHash, Set<u64>, Endowment, Args, R> {
) -> CreateBuilder<E, CodeHash, Set<u64>, Endowment, Args, Salt, R> {
CreateBuilder {
env: Default::default(),
code_hash: self.code_hash,
gas_limit: Set(gas_limit),
endowment: self.endowment,
exec_input: self.exec_input,
salt: self.salt,
return_type: self.return_type,
}
}
}

impl<E, CodeHash, GasLimit, Args, R>
CreateBuilder<E, CodeHash, GasLimit, Unset<E::Balance>, Args, R>
impl<E, CodeHash, GasLimit, Args, Salt, R>
CreateBuilder<E, CodeHash, GasLimit, Unset<E::Balance>, Args, Salt, R>
where
E: Environment,
{
Expand All @@ -244,25 +269,27 @@ where
pub fn endowment(
self,
endowment: E::Balance,
) -> CreateBuilder<E, CodeHash, GasLimit, Set<E::Balance>, Args, R> {
) -> CreateBuilder<E, CodeHash, GasLimit, Set<E::Balance>, Args, Salt, R> {
CreateBuilder {
env: Default::default(),
code_hash: self.code_hash,
gas_limit: self.gas_limit,
endowment: Set(endowment),
exec_input: self.exec_input,
salt: self.salt,
return_type: self.return_type,
}
}
}

impl<E, CodeHash, GasLimit, Endowment, R>
impl<E, CodeHash, GasLimit, Endowment, Salt, R>
CreateBuilder<
E,
CodeHash,
GasLimit,
Endowment,
Unset<ExecutionInput<EmptyArgumentList>>,
Salt,
R,
>
where
Expand All @@ -273,26 +300,54 @@ where
pub fn exec_input<Args>(
self,
exec_input: ExecutionInput<Args>,
) -> CreateBuilder<E, CodeHash, GasLimit, Endowment, Set<ExecutionInput<Args>>, R>
) -> CreateBuilder<E, CodeHash, GasLimit, Endowment, Set<ExecutionInput<Args>>, Salt, R>
{
CreateBuilder {
env: Default::default(),
code_hash: self.code_hash,
gas_limit: self.gas_limit,
endowment: self.endowment,
exec_input: Set(exec_input),
salt: self.salt,
return_type: self.return_type,
}
}
}

impl<E, CodeHash, GasLimit, Endowment, Args, R>
CreateBuilder<E, CodeHash, GasLimit, Endowment, Args, Unset<state::Salt>, R>
where
E: Environment,
{
/// Sets the value transferred upon the execution of the call.
#[inline]
pub fn salt_bytes<Salt>(
self,
salt: Salt,
) -> CreateBuilder<E, CodeHash, GasLimit, Endowment, Args, Set<Salt>, R>
where
Salt: AsRef<[u8]>,
{
CreateBuilder {
env: Default::default(),
code_hash: self.code_hash,
gas_limit: self.gas_limit,
endowment: self.endowment,
exec_input: self.exec_input,
salt: Set(salt),
return_type: self.return_type,
}
}
}

impl<E, GasLimit, Args, R>
impl<E, GasLimit, Args, Salt, R>
CreateBuilder<
E,
Set<E::Hash>,
GasLimit,
Set<E::Balance>,
Set<ExecutionInput<Args>>,
Set<Salt>,
R,
>
where
Expand All @@ -301,30 +356,33 @@ where
{
/// Sets the value transferred upon the execution of the call.
#[inline]
pub fn params(self) -> CreateParams<E, Args, R> {
pub fn params(self) -> CreateParams<E, Args, Salt, R> {
CreateParams {
code_hash: self.code_hash.value(),
gas_limit: self.gas_limit.unwrap_or_else(|| 0),
endowment: self.endowment.value(),
exec_input: self.exec_input.value(),
salt_bytes: self.salt.value(),
return_type: self.return_type,
}
}
}

impl<E, GasLimit, Args, R>
impl<E, GasLimit, Args, Salt, R>
CreateBuilder<
E,
Set<E::Hash>,
GasLimit,
Set<E::Balance>,
Set<ExecutionInput<Args>>,
Set<Salt>,
R,
>
where
E: Environment,
GasLimit: Unwrap<Output = u64>,
Args: scale::Encode,
Salt: AsRef<[u8]>,
R: FromAccountId<E>,
{
/// Instantiates the contract using the given instantiation parameters.
Expand Down
1 change: 1 addition & 0 deletions crates/env/src/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub use self::{
},
create_builder::{
build_create,
state,
CreateBuilder,
CreateParams,
FromAccountId,
Expand Down
4 changes: 2 additions & 2 deletions crates/env/src/engine/off_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,9 +411,9 @@ impl TypedEnvBackend for EnvInstance {
unimplemented!("off-chain environment does not support contract evaluation")
}

fn instantiate_contract<T, Args, C>(
fn instantiate_contract<T, Args, Salt, C>(
&mut self,
_params: &CreateParams<T, Args, C>,
_params: &CreateParams<T, Args, Salt, C>,
) -> Result<T::AccountId>
where
T: Environment,
Expand Down
5 changes: 5 additions & 0 deletions crates/env/src/engine/on_chain/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ mod sys {
address_len_ptr: Ptr32Mut<u32>,
output_ptr: Ptr32Mut<[u8]>,
output_len_ptr: Ptr32Mut<u32>,
salt_ptr: Ptr32<[u8]>,
salt_len: u32,
) -> ReturnCode;

pub fn seal_call(
Expand Down Expand Up @@ -350,6 +352,7 @@ pub fn instantiate(
input: &[u8],
out_address: &mut &mut [u8],
out_return_value: &mut &mut [u8],
salt: &[u8],
) -> Result {
let mut address_len = out_address.len() as u32;
let mut return_value_len = out_return_value.len() as u32;
Expand All @@ -367,6 +370,8 @@ pub fn instantiate(
Ptr32Mut::from_ref(&mut address_len),
Ptr32Mut::from_slice(out_return_value),
Ptr32Mut::from_ref(&mut return_value_len),
Ptr32::from_slice(salt),
salt.len() as u32,
)
}
};
Expand Down
Loading