Skip to content

Commit

Permalink
unified syntax - TxToInto, with optimization attempt
Browse files Browse the repository at this point in the history
  • Loading branch information
andrei-marinica committed Apr 22, 2024
1 parent 68a6df6 commit 4d87c31
Show file tree
Hide file tree
Showing 18 changed files with 262 additions and 82 deletions.
9 changes: 8 additions & 1 deletion contracts/examples/proxy-pause/src/proxy_pause.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,14 @@ pub trait PauseProxy {

fn for_each_contract<F>(&self, f: F)
where
F: Fn(pause_sc_proxy::PausableProxyMethods<TxScEnv<Self::Api>, (), &ManagedAddress, ()>),
F: Fn(
pause_sc_proxy::PausableProxyMethods<
TxScEnv<Self::Api>,
(),
ManagedRef<ManagedAddress>,
(),
>,
),
{
for contract_address in self.contracts().iter() {
f(self
Expand Down
2 changes: 1 addition & 1 deletion contracts/feature-tests/composability/vault/src/vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ pub trait Vault {
));
}

self.tx().to_caller().payment(new_tokens).transfer();
self.tx().to(ToCaller).payment(new_tokens).transfer();
}

#[event("accept_funds")]
Expand Down
6 changes: 3 additions & 3 deletions contracts/modules/src/transfer_role_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub trait TransferRoleProxyModule {
transaction: Tx<
TxScEnv<Self::Api>,
(),
&ManagedAddress,
ManagedRef<'_, ManagedAddress<Self::Api>>,
&ManagedVec<Self::Api, EsdtTokenPayment<Self::Api>>,
(),
FunctionCall<Self::Api>,
Expand Down Expand Up @@ -72,7 +72,7 @@ pub trait TransferRoleProxyModule {
transaction: Tx<
TxScEnv<Self::Api>,
(),
&ManagedAddress,
ManagedRef<'_, ManagedAddress<Self::Api>>,
&ManagedVec<Self::Api, EsdtTokenPayment<Self::Api>>,
(),
FunctionCall<Self::Api>,
Expand All @@ -81,7 +81,7 @@ pub trait TransferRoleProxyModule {
opt_custom_callback: Option<CallbackClosure<Self::Api>>,
) -> ! {
require!(
self.destination_whitelist().contains(transaction.to),
self.destination_whitelist().contains(&transaction.to),
"Destination address not whitelisted"
);

Expand Down
1 change: 1 addition & 0 deletions framework/base/src/api/managed_types/const_handles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub const MBUF_TEMPORARY_2: RawHandle = -26;

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

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

Expand Down
20 changes: 17 additions & 3 deletions framework/base/src/contract_base/wrappers/blockchain_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use crate::{
},
codec::TopDecode,
err_msg::{ONLY_OWNER_CALLER, ONLY_USER_ACCOUNT_CALLER},
storage::{self},
storage,
types::{
BackTransfers, BigUint, CodeMetadata, EgldOrEsdtTokenIdentifier, EsdtLocalRoleFlags,
EsdtTokenData, EsdtTokenType, ManagedAddress, ManagedBuffer, ManagedByteArray, ManagedType,
ManagedVec, TokenIdentifier,
EsdtTokenData, EsdtTokenType, ManagedAddress, ManagedBuffer, ManagedByteArray, ManagedRef,
ManagedType, ManagedVec, TokenIdentifier,
},
};

Expand Down Expand Up @@ -54,6 +54,13 @@ where
ManagedAddress::from_handle(handle)
}

#[inline]
pub fn get_caller_ref(&self) -> ManagedRef<'static, A, ManagedAddress<A>> {
let handle: A::ManagedBufferHandle = use_raw_handle(const_handles::ADDRESS_CALLER);
A::blockchain_api_impl().load_caller_managed(handle.clone());
unsafe { ManagedRef::wrap_handle(handle) }
}

#[deprecated(since = "0.41.0", note = "Please use method `get_sc_address` instead.")]
#[cfg(feature = "alloc")]
#[inline]
Expand All @@ -68,6 +75,13 @@ where
ManagedAddress::from_handle(handle)
}

#[inline]
pub fn get_sc_address_ref(&self) -> ManagedRef<'static, A, ManagedAddress<A>> {
let handle: A::ManagedBufferHandle = use_raw_handle(const_handles::ADDRESS_SELF);
A::blockchain_api_impl().load_sc_address_managed(handle.clone());
unsafe { ManagedRef::wrap_handle(handle) }
}

#[inline]
pub fn get_owner_address(&self) -> ManagedAddress<A> {
let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle());
Expand Down
15 changes: 13 additions & 2 deletions framework/base/src/contract_base/wrappers/send_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::codec::Empty;
use crate::{
api::{BlockchainApi, CallTypeApi, StorageReadApi},
codec,
proxy_imports::ManagedRef,
types::{
system_proxy, BigUint, ContractCallNoPayment, ESDTSystemSCAddress,
EgldOrEsdtTokenIdentifier, EsdtTokenPayment, FunctionCall, GasLeft, ManagedAddress,
Expand Down Expand Up @@ -48,15 +49,25 @@ where
/// Backwards compatibility, synonymous to `esdt_system_sc_tx`, which is the more appropriate name now.
pub fn esdt_system_sc_proxy(
&self,
) -> system_proxy::ESDTSystemSCProxyMethods<TxScEnv<A>, (), ESDTSystemSCAddress, ()> {
) -> system_proxy::ESDTSystemSCProxyMethods<
TxScEnv<A>,
(),
ManagedRef<'static, A, ManagedAddress<A>>,
(),
> {
self.esdt_system_sc_tx()
}

/// Prepares a proxy object to call the system SC.
/// It has the destination address set, as well as the contract type (as specified in the proxy).
pub fn esdt_system_sc_tx(
&self,
) -> system_proxy::ESDTSystemSCProxyMethods<TxScEnv<A>, (), ESDTSystemSCAddress, ()> {
) -> system_proxy::ESDTSystemSCProxyMethods<
TxScEnv<A>,
(),
ManagedRef<'static, A, ManagedAddress<A>>,
(),
> {
Tx::new_tx_from_sc()
.to(ESDTSystemSCAddress)
.typed(system_proxy::ESDTSystemSCProxy)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
storage_clear, storage_get, storage_set,
types::{
system_proxy::ESDTSystemSCProxy, ESDTSystemSCAddress, EgldPayment, FunctionCall,
OriginalResultMarker, Tx, TxScEnv,
ManagedRef, OriginalResultMarker, Tx, TxScEnv,
},
};

Expand Down Expand Up @@ -34,7 +34,7 @@ const INVALID_TOKEN_TYPE_ERR_MSG: &[u8] = b"Invalid token type for NonFungible i
pub type IssueCallTo<Api> = Tx<
TxScEnv<Api>,
(),
ESDTSystemSCAddress,
ManagedRef<'static, Api, ManagedAddress<Api>>,
EgldPayment<Api>,
(),
FunctionCall<Api>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::types::{heap::Address, ManagedAddress, ManagedBuffer};
use crate::{
proxy_imports::ManagedRef,
types::{heap::Address, ManagedAddress, ManagedBuffer},
};

use super::{AnnotatedValue, TxEnv};

Expand Down Expand Up @@ -50,6 +53,31 @@ where
}
}

impl<Env> AnnotatedValue<Env, ManagedAddress<Env::Api>>
for ManagedRef<'_, Env::Api, ManagedAddress<Env::Api>>
where
Env: TxEnv,
{
fn annotation(&self, _env: &Env) -> ManagedBuffer<Env::Api> {
self.hex_expr()
}

fn to_value(&self, _env: &Env) -> ManagedAddress<Env::Api> {
(*self).clone_value()
}

fn into_value(self, _env: &Env) -> ManagedAddress<Env::Api> {
self.clone_value()
}

fn with_value_ref<F, R>(&self, _env: &Env, f: F) -> R
where
F: FnOnce(&ManagedAddress<Env::Api>) -> R,
{
f(self)
}
}

impl<Env> AnnotatedValue<Env, ManagedAddress<Env::Api>> for Address
where
Env: TxEnv,
Expand Down
19 changes: 16 additions & 3 deletions framework/base/src/types/interaction/expr/address_expr.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use core::ptr;

use crate::types::{
AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxFrom, TxFromSpecified, TxTo,
TxToSpecified,
use crate::{
proxy_imports::TxToInto,
types::{
AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxFrom, TxFromSpecified, TxTo,
TxToSpecified,
},
};

const ADDRESS_PREFIX: &str = "address:";
Expand Down Expand Up @@ -38,6 +41,16 @@ where
impl<Env> TxFromSpecified<Env> for AddressExpr where Env: TxEnv {}
impl<Env> TxTo<Env> for AddressExpr where Env: TxEnv {}
impl<Env> TxToSpecified<Env> for AddressExpr where Env: TxEnv {}
impl<Env> TxToInto<Env> for AddressExpr
where
Env: TxEnv,
{
type Into = Self;

fn into_recipient(self) -> Self::Into {
self
}
}

impl AddressExpr {
pub const fn eval_to_array(&self) -> [u8; 32] {
Expand Down
19 changes: 16 additions & 3 deletions framework/base/src/types/interaction/expr/sc_expr.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use core::ptr;

use crate::types::{
heap::Address, AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxFrom, TxFromSpecified,
TxTo, TxToSpecified,
use crate::{
proxy_imports::TxToInto,
types::{
heap::Address, AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxFrom,
TxFromSpecified, TxTo, TxToSpecified,
},
};

const SC_PREFIX: &str = "sc:";
Expand Down Expand Up @@ -47,6 +50,16 @@ where
impl<'a, Env> TxFromSpecified<Env> for ScExpr<'a> where Env: TxEnv {}
impl<'a, Env> TxTo<Env> for ScExpr<'a> where Env: TxEnv {}
impl<'a, Env> TxToSpecified<Env> for ScExpr<'a> where Env: TxEnv {}
impl<'a, Env> TxToInto<Env> for ScExpr<'a>
where
Env: TxEnv,
{
type Into = Self;

fn into_recipient(self) -> Self::Into {
self
}
}

impl<'a> ScExpr<'a> {
pub const fn eval_to_array(&self) -> [u8; 32] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use hex_literal::hex;
use multiversx_sc_codec::{CodecFrom, EncodeErrorHandler, TopEncode, TopEncodeOutput};

use crate::{
api::{CallTypeApi, ManagedTypeApi},
api::{const_handles, use_raw_handle, CallTypeApi, ManagedBufferApiImpl, ManagedTypeApi},
proxy_imports::{ManagedRef, TxToInto},
types::{AnnotatedValue, ManagedAddress, ManagedBuffer, TxScEnv, TxTo, TxToSpecified},
};

Expand Down Expand Up @@ -49,6 +50,18 @@ where

impl<Api> TxTo<TxScEnv<Api>> for ESDTSystemSCAddress where Api: CallTypeApi {}
impl<Api> TxToSpecified<TxScEnv<Api>> for ESDTSystemSCAddress where Api: CallTypeApi {}
impl<Api> TxToInto<TxScEnv<Api>> for ESDTSystemSCAddress
where
Api: CallTypeApi,
{
type Into = ManagedRef<'static, Api, ManagedAddress<Api>>;

fn into_recipient(self) -> Self::Into {
let handle: Api::ManagedBufferHandle = use_raw_handle(const_handles::ADDRESS_ESDT_SYSTEM);
Api::managed_type_impl().mb_overwrite(handle.clone(), &SYSTEM_SC_ADDRESS_BYTES);
unsafe { ManagedRef::wrap_handle(handle) }
}
}

impl TopEncode for ESDTSystemSCAddress {
fn top_encode_or_handle_err<O, H>(&self, output: O, h: H) -> Result<(), H::HandledErr>
Expand Down
30 changes: 7 additions & 23 deletions framework/base/src/types/interaction/markers/to_caller.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,19 @@
use crate::{
api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi},
api::CallTypeApi,
contract_base::BlockchainWrapper,
types::{
AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv, TxTo, TxToSpecified,
},
types::{ManagedAddress, ManagedRef, TxScEnv, TxToInto},
};

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

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

fn to_value(&self, _env: &TxScEnv<Api>) -> ManagedAddress<Api> {
BlockchainWrapper::<Api>::new().get_caller()
}
type Into = ManagedRef<'static, Api, ManagedAddress<Api>>;

fn with_value_ref<F, R>(&self, _env: &TxScEnv<Api>, f: F) -> R
where
F: FnOnce(&ManagedAddress<Api>) -> R,
{
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))
fn into_recipient(self) -> Self::Into {
BlockchainWrapper::<Api>::new().get_caller_ref()
}
}

impl<Api> TxTo<TxScEnv<Api>> for ToCaller where Api: CallTypeApi + BlockchainApi {}
impl<Api> TxToSpecified<TxScEnv<Api>> for ToCaller where Api: CallTypeApi + BlockchainApi {}
31 changes: 7 additions & 24 deletions framework/base/src/types/interaction/markers/to_self.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,19 @@
use crate::{
api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi},
api::CallTypeApi,
contract_base::BlockchainWrapper,
types::{
AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv, TxTo, TxToSpecified,
},
types::{ManagedAddress, ManagedRef, TxScEnv, TxToInto},
};

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

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

fn to_value(&self, _env: &TxScEnv<Api>) -> ManagedAddress<Api> {
BlockchainWrapper::<Api>::new().get_sc_address()
}
type Into = ManagedRef<'static, Api, ManagedAddress<Api>>;

fn with_value_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))
fn into_recipient(self) -> Self::Into {
BlockchainWrapper::<Api>::new().get_sc_address_ref()
}
}

impl<Api> TxTo<TxScEnv<Api>> for ToSelf where Api: CallTypeApi + BlockchainApi {}
impl<Api> TxToSpecified<TxScEnv<Api>> for ToSelf where Api: CallTypeApi + BlockchainApi {}
Loading

0 comments on commit 4d87c31

Please sign in to comment.