Skip to content

Commit

Permalink
Merge pull request #1501 from multiversx/call-local
Browse files Browse the repository at this point in the history
SendWrapper builtin function call refactor
  • Loading branch information
andrei-marinica authored Mar 25, 2024
2 parents a3ac70e + 4f18e7b commit b0aedac
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 37 deletions.
3 changes: 3 additions & 0 deletions framework/base/src/api/managed_types/const_handles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub const CALLBACK_CLOSURE_ARGS_BUFFER: RawHandle = -23;
pub const MBUF_TEMPORARY_1: RawHandle = -25;
pub const MBUF_TEMPORARY_2: RawHandle = -26;

pub const ADDRESS_CALLER: RawHandle = -30;
pub const ADDRESS_SELF: RawHandle = -31;

pub const NEW_HANDLE_START_FROM: RawHandle = -100; // > -100 reserved for APIs

/// Used as a flag. Do not use as a regular handle.
Expand Down
58 changes: 33 additions & 25 deletions framework/base/src/contract_base/wrappers/send_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
},
codec,
esdt::ESDTSystemSmartContractProxy,
proxy_imports::{ReturnsRaw, ToSelf},
types::{
BigUint, ContractCall, ContractCallNoPayment, EgldOrEsdtTokenIdentifier, EsdtTokenPayment,
ManagedAddress, ManagedArgBuffer, ManagedBuffer, ManagedType, ManagedVec, TokenIdentifier,
Expand Down Expand Up @@ -380,11 +381,31 @@ where
pub fn call_local_esdt_built_in_function(
&self,
gas: u64,
endpoint_name: &ManagedBuffer<A>,
arg_buffer: &ManagedArgBuffer<A>,
endpoint_name: ManagedBuffer<A>,
arg_buffer: ManagedArgBuffer<A>,
) -> ManagedVec<A, ManagedBuffer<A>> {
self.send_raw_wrapper()
.call_local_esdt_built_in_function(gas, endpoint_name, arg_buffer)
Tx::new_tx_from_sc()
.to(ToSelf)
.with_gas_limit(gas)
.raw_call()
.function_name(endpoint_name)
.arguments_raw(arg_buffer)
.returns(ReturnsRaw)
.sync_call()
}

fn call_local_esdt_built_in_function_minimal(
&self,
function_name: &str,
arg_buffer: ManagedArgBuffer<A>,
) {
Tx::new_tx_from_sc()
.to(ToSelf)
.with_gas_limit(A::blockchain_api_impl().get_gas_left())
.raw_call()
.function_name(function_name)
.arguments_raw(arg_buffer)
.sync_call()
}

/// Allows synchronous minting of ESDT/SFT (depending on nonce). Execution is resumed afterwards.
Expand All @@ -410,11 +431,7 @@ where

arg_buffer.push_arg(amount);

let _ = self.call_local_esdt_built_in_function(
A::blockchain_api_impl().get_gas_left(),
&ManagedBuffer::from(func_name),
&arg_buffer,
);
self.call_local_esdt_built_in_function_minimal(func_name, arg_buffer);
}

/// Allows synchronous minting of ESDT/SFT (depending on nonce). Execution is resumed afterwards.
Expand Down Expand Up @@ -456,11 +473,7 @@ where

arg_buffer.push_arg(amount);

let _ = self.call_local_esdt_built_in_function(
A::blockchain_api_impl().get_gas_left(),
&ManagedBuffer::from(func_name),
&arg_buffer,
);
self.call_local_esdt_built_in_function_minimal(func_name, arg_buffer);
}

/// Allows synchronous burning of ESDT/SFT/NFT (depending on nonce). Execution is resumed afterwards.
Expand Down Expand Up @@ -549,8 +562,8 @@ where

let output = self.call_local_esdt_built_in_function(
A::blockchain_api_impl().get_gas_left(),
&ManagedBuffer::from(ESDT_NFT_CREATE_FUNC_NAME),
&arg_buffer,
ManagedBuffer::from(ESDT_NFT_CREATE_FUNC_NAME),
arg_buffer,
);

if let Some(first_result_bytes) = output.try_get(0) {
Expand Down Expand Up @@ -770,11 +783,7 @@ where
arg_buffer.push_arg(uri);
}

let _ = self.call_local_esdt_built_in_function(
A::blockchain_api_impl().get_gas_left(),
&ManagedBuffer::from(ESDT_NFT_ADD_URI_FUNC_NAME),
&arg_buffer,
);
self.call_local_esdt_built_in_function_minimal(ESDT_NFT_ADD_URI_FUNC_NAME, arg_buffer);
}

/// Changes attributes of an NFT, via a synchronous builtin function call.
Expand All @@ -789,10 +798,9 @@ where
arg_buffer.push_arg(nft_nonce);
arg_buffer.push_arg(new_attributes);

let _ = self.call_local_esdt_built_in_function(
A::blockchain_api_impl().get_gas_left(),
&ManagedBuffer::from(ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME),
&arg_buffer,
self.call_local_esdt_built_in_function_minimal(
ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME,
arg_buffer,
);
}
}
2 changes: 2 additions & 0 deletions framework/base/src/types/interaction/tx_to.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
mod tx_to_caller;
mod tx_to_self;

pub use tx_to_caller::ToCaller;
pub use tx_to_self::ToSelf;

use crate::types::{heap::Address, ManagedAddress};

Expand Down
19 changes: 7 additions & 12 deletions framework/base/src/types/interaction/tx_to/tx_to_caller.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
use crate::{
api::{BlockchainApi, CallTypeApi},
api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi},
contract_base::BlockchainWrapper,
types::{AnnotatedValue, ManagedAddress, ManagedBuffer, TxScEnv},
types::{AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv},
};

use super::{TxTo, TxToSpecified};

/// Indicates that transaction should be sent to the caller (the sender of the current transaction).
pub struct ToCaller;

fn get_caller<Api>() -> ManagedAddress<Api>
where
Api: CallTypeApi + BlockchainApi,
{
BlockchainWrapper::<Api>::new().get_caller()
}

impl<Api> AnnotatedValue<TxScEnv<Api>, ManagedAddress<Api>> for ToCaller
where
Api: CallTypeApi + BlockchainApi,
{
fn annotation(&self, env: &TxScEnv<Api>) -> ManagedBuffer<Api> {
get_caller::<Api>().hex_expr()
self.with_address_ref(env, |addr_ref| addr_ref.hex_expr())
}

fn into_value(self, _env: &TxScEnv<Api>) -> ManagedAddress<Api> {
get_caller::<Api>()
BlockchainWrapper::<Api>::new().get_caller()
}
}

Expand All @@ -38,6 +31,8 @@ where
where
F: FnOnce(&ManagedAddress<Api>) -> R,
{
f(&get_caller::<Api>())
let caller_handle: Api::ManagedBufferHandle = use_raw_handle(const_handles::ADDRESS_CALLER);
Api::blockchain_api_impl().load_caller_managed(caller_handle.clone());
f(&ManagedAddress::from_handle(caller_handle))
}
}
38 changes: 38 additions & 0 deletions framework/base/src/types/interaction/tx_to/tx_to_self.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::{
api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi},
contract_base::BlockchainWrapper,
types::{AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv},
};

use super::{TxTo, TxToSpecified};

/// Indicates that transaction should be sent to itself.
pub struct ToSelf;

impl<Api> AnnotatedValue<TxScEnv<Api>, ManagedAddress<Api>> for ToSelf
where
Api: CallTypeApi + BlockchainApi,
{
fn annotation(&self, env: &TxScEnv<Api>) -> ManagedBuffer<Api> {
self.with_address_ref(env, |addr_ref| addr_ref.hex_expr())
}

fn into_value(self, _env: &TxScEnv<Api>) -> ManagedAddress<Api> {
BlockchainWrapper::<Api>::new().get_sc_address()
}
}

impl<Api> TxTo<TxScEnv<Api>> for ToSelf where Api: CallTypeApi + BlockchainApi {}
impl<Api> TxToSpecified<TxScEnv<Api>> for ToSelf
where
Api: CallTypeApi + BlockchainApi,
{
fn with_address_ref<F, R>(&self, env: &TxScEnv<Api>, f: F) -> R
where
F: FnOnce(&ManagedAddress<Api>) -> R,
{
let sc_address_handle: Api::ManagedBufferHandle = use_raw_handle(const_handles::ADDRESS_CALLER);
Api::blockchain_api_impl().load_sc_address_managed(sc_address_handle.clone());
f(&ManagedAddress::from_handle(sc_address_handle))
}
}

0 comments on commit b0aedac

Please sign in to comment.