Skip to content

Commit

Permalink
Unify ink_env::{eval_contract, invoke_contract} (#1165)
Browse files Browse the repository at this point in the history
* Merge contract invoke and eval

* Fix up call builder

* Fmt

* Restore off chain param getters

* Use ReturnType in generated CallBuilder

* No longer need to explicitly wrap return type in ReturnType

* Fmt

* Remove some unused ReturnType usage

* Default to `returns::<()>()`, remove ReturnType usage in api

* Fmt

* Fix UI test

* Another UI test
  • Loading branch information
ascjones authored Mar 7, 2022
1 parent 3122bad commit 776df42
Show file tree
Hide file tree
Showing 14 changed files with 74 additions and 272 deletions.
33 changes: 3 additions & 30 deletions crates/env/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use crate::{
TypedEnvBackend,
},
call::{
utils::ReturnType,
CallParams,
CreateParams,
},
Expand Down Expand Up @@ -216,33 +215,7 @@ pub fn clear_contract_storage(key: &Key) {
})
}

/// Invokes a contract message.
///
/// # Note
///
/// - Prefer using this over [`eval_contract`] if possible. [`invoke_contract`]
/// will generally have a better performance since it won't try to fetch any results.
/// - This is a low level way to invoke another smart contract.
/// Prefer to use the ink! guided and type safe approach to using this.
///
/// # Errors
///
/// - If the called account does not exist.
/// - If the called account is not a contract.
/// - If arguments passed to the called contract message are invalid.
/// - If the called contract execution has trapped.
/// - If the called contract ran out of gas upon execution.
pub fn invoke_contract<T, Args>(params: &CallParams<T, Args, ()>) -> Result<()>
where
T: Environment,
Args: scale::Encode,
{
<EnvInstance as OnInstance>::on_instance(|instance| {
TypedEnvBackend::invoke_contract::<T, Args>(instance, params)
})
}

/// Evaluates a contract message and returns its result.
/// Invokes a contract message and returns its result.
///
/// # Note
///
Expand All @@ -257,14 +230,14 @@ where
/// - If the called contract execution has trapped.
/// - If the called contract ran out of gas upon execution.
/// - If the returned value failed to decode properly.
pub fn eval_contract<T, Args, R>(params: &CallParams<T, Args, ReturnType<R>>) -> Result<R>
pub fn invoke_contract<T, Args, R>(params: &CallParams<T, Args, R>) -> Result<R>
where
T: Environment,
Args: scale::Encode,
R: scale::Decode,
{
<EnvInstance as OnInstance>::on_instance(|instance| {
TypedEnvBackend::eval_contract::<T, Args, R>(instance, params)
TypedEnvBackend::invoke_contract::<T, Args, R>(instance, params)
})
}

Expand Down
20 changes: 3 additions & 17 deletions crates/env/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

use crate::{
call::{
utils::ReturnType,
CallParams,
CreateParams,
},
Expand Down Expand Up @@ -359,27 +358,14 @@ pub trait TypedEnvBackend: EnvBackend {
T: Environment,
Event: Topics + scale::Encode;

/// Invokes a contract message.
/// Invokes a contract message and returns its result.
///
/// # Note
///
/// For more details visit: [`invoke_contract`][`crate::invoke_contract`]
fn invoke_contract<T, Args>(
fn invoke_contract<T, Args, R>(
&mut self,
call_data: &CallParams<T, Args, ()>,
) -> Result<()>
where
T: Environment,
Args: scale::Encode;

/// Evaluates a contract message and returns its result.
///
/// # Note
///
/// For more details visit: [`eval_contract`][`crate::eval_contract`]
fn eval_contract<T, Args, R>(
&mut self,
call_data: &CallParams<T, Args, ReturnType<R>>,
call_data: &CallParams<T, Args, R>,
) -> Result<R>
where
T: Environment,
Expand Down
77 changes: 10 additions & 67 deletions crates/env/src/call/call_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,38 +84,17 @@ where
}
}

impl<E, Args> CallParams<E, Args, ()>
where
E: Environment,
Args: scale::Encode,
{
/// Invokes the contract with the given built-up call parameters.
///
/// # Note
///
/// Prefer [`invoke`](`Self::invoke`) over [`eval`](`Self::eval`) if the
/// called contract message does not return anything because it is more efficient.
pub fn invoke(&self) -> Result<(), crate::Error> {
crate::invoke_contract(self)
}
}

impl<E, Args, R> CallParams<E, Args, ReturnType<R>>
impl<E, Args, R> CallParams<E, Args, R>
where
E: Environment,
Args: scale::Encode,
R: scale::Decode,
{
/// Evaluates the contract with the given built-up call parameters.
/// Invokes the contract with the given built-up call parameters.
///
/// Returns the result of the contract execution.
///
/// # Note
///
/// Prefer [`invoke`](`Self::invoke`) over [`eval`](`Self::eval`) if the
/// called contract message does not return anything because it is more efficient.
pub fn eval(&self) -> Result<R, crate::Error> {
crate::eval_contract(self)
pub fn invoke(&self) -> Result<R, crate::Error> {
crate::invoke_contract(self)
}
}

Expand Down Expand Up @@ -179,7 +158,7 @@ where
/// # use ::ink_env::{
/// # Environment,
/// # DefaultEnvironment,
/// # call::{build_call, Selector, ExecutionInput, utils::ReturnType},
/// # call::{build_call, Selector, ExecutionInput},
/// # };
/// # type AccountId = <DefaultEnvironment as Environment>::AccountId;
/// let my_return_value: i32 = build_call::<DefaultEnvironment>()
Expand All @@ -192,7 +171,7 @@ where
/// .push_arg(true)
/// .push_arg(&[0x10; 32])
/// )
/// .returns::<ReturnType<i32>>()
/// .returns::<i32>()
/// .fire()
/// .unwrap();
/// ```
Expand Down Expand Up @@ -328,18 +307,6 @@ where
}
}

mod seal {
/// Used to prevent users from implementing `IndicateReturnType` for their own types.
pub trait Sealed {}
impl Sealed for () {}
impl<T> Sealed for super::ReturnType<T> {}
}

/// Types that can be used in [`CallBuilder::returns`] to signal return type.
pub trait IndicateReturnType: Default + self::seal::Sealed {}
impl IndicateReturnType for () {}
impl<T> IndicateReturnType for ReturnType<T> {}

impl<E, Callee, GasLimit, TransferredValue, Args>
CallBuilder<E, Callee, GasLimit, TransferredValue, Args, Unset<ReturnType<()>>>
where
Expand All @@ -350,14 +317,11 @@ where
/// # Note
///
/// Either use `.returns::<()>` to signal that the call does not return a value
/// or use `.returns::<ReturnType<T>>` to signal that the call returns a value of
/// type `T`.
/// or use `.returns::<T>` to signal that the call returns a value of type `T`.
#[inline]
pub fn returns<R>(
self,
) -> CallBuilder<E, Callee, GasLimit, TransferredValue, Args, Set<R>>
where
R: IndicateReturnType,
) -> CallBuilder<E, Callee, GasLimit, TransferredValue, Args, Set<ReturnType<R>>>
{
CallBuilder {
env: Default::default(),
Expand Down Expand Up @@ -414,7 +378,7 @@ impl<E, GasLimit, TransferredValue, Args, RetType>
GasLimit,
TransferredValue,
Set<ExecutionInput<Args>>,
Set<RetType>,
Set<ReturnType<RetType>>,
>
where
E: Environment,
Expand Down Expand Up @@ -465,27 +429,6 @@ where
}
}

impl<E, GasLimit, TransferredValue, Args>
CallBuilder<
E,
Set<E::AccountId>,
GasLimit,
TransferredValue,
Set<ExecutionInput<Args>>,
Set<()>,
>
where
E: Environment,
GasLimit: Unwrap<Output = u64>,
Args: scale::Encode,
TransferredValue: Unwrap<Output = E::Balance>,
{
/// Invokes the cross-chain function call.
pub fn fire(self) -> Result<(), Error> {
self.params().invoke()
}
}

impl<E, GasLimit, TransferredValue>
CallBuilder<
E,
Expand Down Expand Up @@ -524,6 +467,6 @@ where
{
/// Invokes the cross-chain function call and returns the result.
pub fn fire(self) -> Result<R, Error> {
self.params().eval()
self.params().invoke()
}
}
2 changes: 1 addition & 1 deletion crates/env/src/call/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use core::marker::PhantomData;

/// Represents a return type.
///
/// Used as a marker type to differentiate at compile-time between invoke and evaluate.
/// Used as a marker type to define the return type of an ink! message in call builders.
#[derive(Debug)]
pub struct ReturnType<T>(PhantomData<fn() -> T>);

Expand Down
1 change: 0 additions & 1 deletion crates/env/src/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ mod selector;
/// Utility types for the cross-contract calling API.
pub mod utils {
pub use super::{
call_builder::IndicateReturnType,
common::{
ReturnType,
Set,
Expand Down
19 changes: 5 additions & 14 deletions crates/env/src/engine/off_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use super::EnvInstance;
use crate::{
call::{
utils::ReturnType,
CallParams,
CreateParams,
},
Expand Down Expand Up @@ -387,10 +386,14 @@ impl TypedEnvBackend for EnvInstance {
self.engine.deposit_event(&enc_topics[..], enc_data);
}

fn invoke_contract<T, Args>(&mut self, params: &CallParams<T, Args, ()>) -> Result<()>
fn invoke_contract<T, Args, R>(
&mut self,
params: &CallParams<T, Args, R>,
) -> Result<R>
where
T: Environment,
Args: scale::Encode,
R: scale::Decode,
{
let _gas_limit = params.gas_limit();
let _callee = params.callee();
Expand All @@ -400,18 +403,6 @@ impl TypedEnvBackend for EnvInstance {
unimplemented!("off-chain environment does not support contract invocation")
}

fn eval_contract<T, Args, R>(
&mut self,
_call_params: &CallParams<T, Args, ReturnType<R>>,
) -> Result<R>
where
T: Environment,
Args: scale::Encode,
R: scale::Decode,
{
unimplemented!("off-chain environment does not support contract evaluation")
}

fn instantiate_contract<T, Args, Salt, C>(
&mut self,
params: &CreateParams<T, Args, Salt, C>,
Expand Down
Loading

0 comments on commit 776df42

Please sign in to comment.