Unverified Commit d42bfbfd authored by Sasha Gryaznov's avatar Sasha Gryaznov Committed by GitHub
Browse files

Add `ink_env::pay_with_call!` helper macro for off-chain emulation of sending...


Add `ink_env::pay_with_call!` helper macro for off-chain emulation of sending payments with contract msg calls (#1379)

* first ver.: transfer_in api function implememted but we can't have it in on-chain env

* transfer_in moved to test_api

* doc + example updated

* Update examples/contract-transfer/lib.rs
Co-authored-by: default avatarHernando Castano <HCastano@users.noreply.github.com>

* use stmt moved to macro

* docs and nitty gritties

* moved the macro to the test mod

* spell fix

* next review round suggestions applied

* Use four spaces for macro indentation
Co-authored-by: default avatarHernando Castano <HCastano@users.noreply.github.com>
Co-authored-by: default avatarHernando Castano <hernando@hcastano.com>
parent fb871a04
Pipeline #214657 failed with stages
in 10 minutes and 52 seconds
......@@ -200,6 +200,8 @@ where
}
/// Sets the value transferred from the caller to the callee as part of the call.
///
/// Please note that the acting accounts should be set with [`set_caller()`] and [`set_callee()`] beforehand.
pub fn set_value_transferred<T>(value: T::Balance)
where
T: Environment<Balance = u128>, // Just temporary for the MVP!
......@@ -209,6 +211,44 @@ where
})
}
/// Transfers value from the caller account to the contract.
///
/// Please note that the acting accounts should be set with [`set_caller()`] and [`set_callee()`] beforehand.
pub fn transfer_in<T>(value: T::Balance)
where
T: Environment<Balance = u128>, // Just temporary for the MVP!
{
<EnvInstance as OnInstance>::on_instance(|instance| {
let caller = instance
.engine
.exec_context
.caller
.as_ref()
.expect("no caller has been set")
.as_bytes()
.to_vec();
let caller_old_balance = instance
.engine
.get_balance(caller.clone())
.unwrap_or_default();
let callee = instance.engine.get_callee();
let contract_old_balance = instance
.engine
.get_balance(callee.clone())
.unwrap_or_default();
instance
.engine
.set_balance(caller, caller_old_balance - value);
instance
.engine
.set_balance(callee, contract_old_balance + value);
instance.engine.set_value_transferred(value);
});
}
/// Returns the amount of storage cells used by the account `account_id`.
///
/// Returns `None` if the `account_id` is non-existent.
......@@ -355,3 +395,12 @@ pub fn assert_contract_termination<T, F>(
assert_eq!(value_transferred, expected_value_transferred_to_beneficiary);
assert_eq!(beneficiary, expected_beneficiary);
}
/// Prepend contract message call with value transfer. Used for tests in off-chain environment.
#[macro_export]
macro_rules! pay_with_call {
($contract:ident . $message:ident ( $($params:ty)? ) , $amount:expr) => {{
$crate::test::transfer_in::<Environment>($amount);
$contract.$message($($params:ty)?)
}}
}
......@@ -101,20 +101,31 @@ pub mod give_me {
#[ink::test]
fn test_transferred_value() {
use ink_lang::codegen::Env;
// given
let accounts = default_accounts();
let give_me = create_contract(100);
let contract_account = give_me.env().account_id();
// when
// Push the new execution context which sets Eve as caller and
// the `mock_transferred_value` as the value which the contract
// will see as transferred to it.
// Push the new execution context which sets initial balances and
// sets Eve as the caller
set_balance(accounts.eve, 100);
set_balance(contract_account, 0);
set_sender(accounts.eve);
ink_env::test::set_value_transferred::<ink_env::DefaultEnvironment>(10);
// then
// there must be no panic
give_me.was_it_ten();
// we use helper macro to emulate method invocation coming with payment,
// and there must be no panic
ink_env::pay_with_call!(give_me.was_it_ten(), 10);
// and
// balances should be changed properly
let contract_new_balance = get_balance(contract_account);
let caller_new_balance = get_balance(accounts.eve);
assert_eq!(caller_new_balance, 100 - 10);
assert_eq!(contract_new_balance, 10);
}
#[ink::test]
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment