From 1e95bad87d036e0e5971dc5fd3416827f6e8cfe0 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 22 Mar 2024 22:31:16 +0200 Subject: [PATCH] tx payment refactor - with_normalized moved back to TxPayment --- .../interaction/contract_call_convert.rs | 6 +- .../src/types/interaction/function_call.rs | 8 +- framework/base/src/types/interaction/tx.rs | 6 +- .../src/types/interaction/tx_call_async.rs | 4 +- .../interaction/tx_call_async_promises.rs | 4 +- .../src/types/interaction/tx_call_sync.rs | 7 +- .../base/src/types/interaction/tx_payment.rs | 22 ++- .../interaction/tx_payment/tx_payment_egld.rs | 21 +- .../tx_payment/tx_payment_multi_esdt.rs | 41 +++- .../interaction/tx_payment/tx_payment_none.rs | 18 +- .../tx_payment/tx_payment_normalize.rs | 182 ------------------ .../tx_payment/tx_payment_other.rs | 44 +++++ .../tx_payment/tx_payment_single_esdt.rs | 29 ++- 13 files changed, 185 insertions(+), 207 deletions(-) delete mode 100644 framework/base/src/types/interaction/tx_payment/tx_payment_normalize.rs diff --git a/framework/base/src/types/interaction/contract_call_convert.rs b/framework/base/src/types/interaction/contract_call_convert.rs index c7e4301c2c..88e6ae6627 100644 --- a/framework/base/src/types/interaction/contract_call_convert.rs +++ b/framework/base/src/types/interaction/contract_call_convert.rs @@ -38,7 +38,7 @@ where function_call: self .basic .function_call - .convert_to_single_transfer_fungible_call(payment), + .convert_to_single_transfer_fungible_call(&payment), explicit_gas_limit: self.basic.explicit_gas_limit, _return_type: PhantomData, }, @@ -55,7 +55,7 @@ where function_call: self .basic .function_call - .convert_to_single_transfer_nft_call(&self.basic.to, payment), + .convert_to_single_transfer_nft_call(&self.basic.to, &payment), explicit_gas_limit: self.basic.explicit_gas_limit, _return_type: PhantomData, }, @@ -78,7 +78,7 @@ where function_call: self .basic .function_call - .convert_to_multi_transfer_esdt_call(&self.basic.to, payments), + .convert_to_multi_transfer_esdt_call(&self.basic.to, &payments), explicit_gas_limit: self.basic.explicit_gas_limit, _return_type: PhantomData, }, diff --git a/framework/base/src/types/interaction/function_call.rs b/framework/base/src/types/interaction/function_call.rs index 8a1e298419..efb149e2b4 100644 --- a/framework/base/src/types/interaction/function_call.rs +++ b/framework/base/src/types/interaction/function_call.rs @@ -159,7 +159,7 @@ where /// Constructs `ESDTTransfer` builtin function call. pub(super) fn convert_to_single_transfer_fungible_call( self, - payment: EsdtTokenPayment, + payment: &EsdtTokenPayment, ) -> FunctionCall { FunctionCall::new(ESDT_TRANSFER_FUNC_NAME) .argument(&payment.token_identifier) @@ -177,7 +177,7 @@ where pub(super) fn convert_to_single_transfer_nft_call( self, to: &ManagedAddress, - payment: EsdtTokenPayment, + payment: &EsdtTokenPayment, ) -> FunctionCall { FunctionCall::new(ESDT_NFT_TRANSFER_FUNC_NAME) .argument(&payment.token_identifier) @@ -191,13 +191,13 @@ where pub(super) fn convert_to_multi_transfer_esdt_call( self, to: &ManagedAddress, - payments: ManagedVec>, + payments: &ManagedVec>, ) -> FunctionCall { let mut result = FunctionCall::new(ESDT_MULTI_TRANSFER_FUNC_NAME) .argument(&to) .argument(&payments.len()); - for payment in payments.into_iter() { + for payment in payments { result = result .argument(&payment.token_identifier) .argument(&payment.token_nonce) diff --git a/framework/base/src/types/interaction/tx.rs b/framework/base/src/types/interaction/tx.rs index db6c244bd6..9e41ae8b2d 100644 --- a/framework/base/src/types/interaction/tx.rs +++ b/framework/base/src/types/interaction/tx.rs @@ -14,8 +14,8 @@ use super::{ ContractCallNoPayment, ContractCallWithEgld, ContractDeploy, DeployCall, Egld, EgldPayment, ExplicitGas, FromSource, FunctionCall, ManagedArgBuffer, OriginalResultMarker, RHList, RHListAppendNoRet, RHListAppendRet, RHListItem, TxCodeSource, TxCodeValue, TxData, TxEgldValue, - TxEnv, TxFrom, TxFromSourceValue, TxGas, TxPayment, TxPaymentEgldOnly, TxPaymentNormalize, - TxProxyTrait, TxResultHandler, TxScEnv, TxTo, TxToSpecified, + TxEnv, TxFrom, TxFromSourceValue, TxGas, TxPayment, TxPaymentEgldOnly, TxProxyTrait, + TxResultHandler, TxScEnv, TxTo, TxToSpecified, }; #[must_use] @@ -565,7 +565,7 @@ impl ContractCallBase where Api: CallTypeApi + 'static, To: TxToSpecified>, - Payment: TxPaymentNormalize, (), To>, + Payment: TxPayment>, OriginalResult: TopEncodeMulti, { type OriginalResult = OriginalResult; diff --git a/framework/base/src/types/interaction/tx_call_async.rs b/framework/base/src/types/interaction/tx_call_async.rs index 3e77979c2e..daa69013cf 100644 --- a/framework/base/src/types/interaction/tx_call_async.rs +++ b/framework/base/src/types/interaction/tx_call_async.rs @@ -6,7 +6,7 @@ use crate::{ use super::{ OriginalResultMarker, Tx, TxData, TxDataFunctionCall, TxEnv, TxFrom, TxGas, TxPayment, - TxPaymentNormalize, TxResultHandler, TxScEnv, TxTo, TxToSpecified, + TxResultHandler, TxScEnv, TxTo, TxToSpecified, }; pub trait TxAsyncCallCallback: TxResultHandler> @@ -119,7 +119,7 @@ impl Tx, (), To, Payment, (), FC, RH> where Api: CallTypeApi, To: TxToSpecified>, - Payment: TxPaymentNormalize, (), To>, + Payment: TxPayment>, FC: TxDataFunctionCall>, RH: TxAsyncCallCallback, { diff --git a/framework/base/src/types/interaction/tx_call_async_promises.rs b/framework/base/src/types/interaction/tx_call_async_promises.rs index 134d2e0081..f2560451cf 100644 --- a/framework/base/src/types/interaction/tx_call_async_promises.rs +++ b/framework/base/src/types/interaction/tx_call_async_promises.rs @@ -6,7 +6,7 @@ use crate::{ use super::{ callback_closure::CallbackClosureWithGas, ExplicitGas, FunctionCall, OriginalResultMarker, Tx, - TxGas, TxPayment, TxPaymentNormalize, TxResultHandler, TxScEnv, TxToSpecified, + TxGas, TxPayment, TxResultHandler, TxScEnv, TxToSpecified, }; pub trait TxPromisesCallback: TxResultHandler> @@ -122,7 +122,7 @@ impl where Api: CallTypeApi, To: TxToSpecified>, - Payment: TxPaymentNormalize, (), To>, + Payment: TxPayment>, Callback: TxPromisesCallback, { pub fn register_promise(self) { diff --git a/framework/base/src/types/interaction/tx_call_sync.rs b/framework/base/src/types/interaction/tx_call_sync.rs index 0213a1df75..61c73a7b0c 100644 --- a/framework/base/src/types/interaction/tx_call_sync.rs +++ b/framework/base/src/types/interaction/tx_call_sync.rs @@ -9,8 +9,7 @@ use crate::{ use super::{ contract_call_exec::decode_result, BackTransfers, ConsNoRet, ConsRet, OriginalResultMarker, - RHList, RHListItem, Tx, TxDataFunctionCall, TxEnv, TxGas, TxPaymentNormalize, TxScEnv, - TxToSpecified, + RHList, RHListItem, Tx, TxDataFunctionCall, TxEnv, TxGas, TxPayment, TxScEnv, TxToSpecified, }; pub trait RHListItemSync: RHListItem @@ -90,7 +89,7 @@ impl Tx, (), To, Payment, Gas, FC, R where Api: CallTypeApi, To: TxToSpecified>, - Payment: TxPaymentNormalize, (), To>, + Payment: TxPayment>, Gas: TxGas>, FC: TxDataFunctionCall>, RH: RHListSync>, @@ -133,7 +132,7 @@ impl where Api: CallTypeApi, To: TxToSpecified>, - Payment: TxPaymentNormalize, (), To>, + Payment: TxPayment>, Gas: TxGas>, FC: TxDataFunctionCall>, { diff --git a/framework/base/src/types/interaction/tx_payment.rs b/framework/base/src/types/interaction/tx_payment.rs index af40f79f56..2511d2ede8 100644 --- a/framework/base/src/types/interaction/tx_payment.rs +++ b/framework/base/src/types/interaction/tx_payment.rs @@ -2,13 +2,11 @@ mod tx_payment_egld; mod tx_payment_egld_value; mod tx_payment_multi_esdt; mod tx_payment_none; -mod tx_payment_normalize; mod tx_payment_other; mod tx_payment_single_esdt; pub use tx_payment_egld::{Egld, EgldPayment}; pub use tx_payment_egld_value::TxEgldValue; -pub use tx_payment_normalize::TxPaymentNormalize; use crate::{ api::ManagedTypeApi, @@ -19,15 +17,18 @@ use crate::{ }, }; -use super::{FunctionCall, TxEnv}; +use super::{FunctionCall, TxEnv, TxFrom, TxToSpecified}; /// Describes a payment that is part of a transaction. pub trait TxPayment where Env: TxEnv, { + /// Returns true if payment indicates transfer of either non-zero EGLD or ESDT amounts. fn is_no_payment(&self) -> bool; + /// Transfer-execute calls have different APIs for different payments types. + /// This method selects between them. fn perform_transfer_execute( self, env: &Env, @@ -36,6 +37,21 @@ where fc: FunctionCall, ); + /// Converts an ESDT call to a built-in function call, if necessary. + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R; + + /// Payment data to be used by the testing framework. Will be refactored. fn into_full_payment_data(self, env: &Env) -> FullPaymentData; } diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld.rs index f84d6afacb..a4881bda05 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_egld.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld.rs @@ -1,6 +1,6 @@ use crate::{ contract_base::SendRawWrapper, - types::{BigUint, ManagedAddress, ManagedVec}, + types::{BigUint, ManagedAddress, ManagedVec, TxFrom, TxToSpecified}, }; use super::{ @@ -40,6 +40,25 @@ where }) } + fn with_normalized( + self, + env: &Env, + _from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, + { + to.with_address_ref(env, |to_addr| { + self.0 + .with_egld_value(|egld_value| f(to_addr, egld_value, &fc)) + }) + } + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { FullPaymentData { egld: Some(AnnotatedEgldPayment::new_egld(self.0.into_value(env))), diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_multi_esdt.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_multi_esdt.rs index 84a8de5e5b..de9f65eff9 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_multi_esdt.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_multi_esdt.rs @@ -1,6 +1,6 @@ use crate::{ contract_base::SendRawWrapper, - types::{BigUint, ManagedAddress, ManagedVec, MultiEsdtPayment}, + types::{BigUint, ManagedAddress, ManagedVec, MultiEsdtPayment, TxFrom, TxToSpecified}, }; use super::{AnnotatedEgldPayment, FullPaymentData, FunctionCall, TxEgldValue, TxEnv, TxPayment}; @@ -29,6 +29,29 @@ where ); } + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, + { + match self.len() { + 0 => ().with_normalized(env, from, to, fc, f), + 1 => self.get(0).with_normalized(env, from, to, fc, f), + _ => to.with_address_ref(env, |to_addr| { + let fc_conv = fc.convert_to_multi_transfer_esdt_call(to_addr, self); + f(&from.resolve_address(env), &BigUint::zero(), &fc_conv) + }), + } + } + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { FullPaymentData { egld: None, @@ -55,6 +78,22 @@ where (&self).perform_transfer_execute(env, to, gas_limit, fc); } + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, + { + (&self).with_normalized(env, from, to, fc, f) + } + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { FullPaymentData { egld: None, diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_none.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_none.rs index 7b34ccfe9b..d97143a2ad 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_none.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_none.rs @@ -1,6 +1,6 @@ use crate::{ contract_base::SendRawWrapper, - types::{BigUint, ManagedAddress, ManagedVec}, + types::{BigUint, ManagedAddress, ManagedVec, TxFrom, TxToSpecified}, }; use super::{ @@ -26,6 +26,22 @@ where Egld(BigUint::zero()).perform_transfer_execute(env, to, gas_limit, fc); } + fn with_normalized( + self, + env: &Env, + _from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, + { + to.with_address_ref(env, |to_addr| f(to_addr, &BigUint::zero(), &fc)) + } + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { FullPaymentData::default() } diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_normalize.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_normalize.rs deleted file mode 100644 index db263fa83f..0000000000 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_normalize.rs +++ /dev/null @@ -1,182 +0,0 @@ -use crate::types::{ - BigUint, EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, EsdtTokenPayment, ManagedAddress, - MultiEsdtPayment, TxFrom, TxToSpecified, -}; - -use super::{Egld, FunctionCall, TxEgldValue, TxEnv, TxPayment}; - -/// Defines how a payment transforms a transaction, -/// e.g. from ESDT transfer to ESDTTransfer builtin function. -pub trait TxPaymentNormalize: TxPayment -where - Env: TxEnv, - From: TxFrom, - To: TxToSpecified, -{ - fn with_normalized( - self, - env: &Env, - from: &From, - to: To, - fc: FunctionCall, - f: F, - ) -> R - where - F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R; -} - -impl TxPaymentNormalize for () -where - Env: TxEnv, - From: TxFrom, - To: TxToSpecified, -{ - fn with_normalized( - self, - env: &Env, - _from: &From, - to: To, - fc: FunctionCall, - f: F, - ) -> R - where - F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, - { - to.with_address_ref(env, |to_addr| f(to_addr, &BigUint::zero(), &fc)) - } -} - -impl TxPaymentNormalize for Egld -where - Env: TxEnv, - From: TxFrom, - To: TxToSpecified, - EgldValue: TxEgldValue, -{ - fn with_normalized( - self, - env: &Env, - _from: &From, - to: To, - fc: FunctionCall, - f: F, - ) -> R - where - F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, - { - to.with_address_ref(env, |to_addr| { - self.0 - .with_egld_value(|egld_value| f(to_addr, egld_value, &fc)) - }) - } -} - -impl TxPaymentNormalize for EsdtTokenPayment -where - Env: TxEnv, - From: TxFrom, - To: TxToSpecified, -{ - fn with_normalized( - self, - env: &Env, - from: &From, - to: To, - fc: FunctionCall, - f: F, - ) -> R - where - F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, - { - to.with_address_ref(env, |to_addr| { - if self.token_nonce == 0 { - let fc_conv = fc.convert_to_single_transfer_fungible_call(self); - f(to_addr, &BigUint::zero(), &fc_conv) - } else { - let fc_conv = fc.convert_to_single_transfer_nft_call(to_addr, self); - f(&from.resolve_address(env), &BigUint::zero(), &fc_conv) - } - }) - } -} - -impl TxPaymentNormalize for MultiEsdtPayment -where - Env: TxEnv, - From: TxFrom, - To: TxToSpecified, -{ - fn with_normalized( - self, - env: &Env, - from: &From, - to: To, - fc: FunctionCall, - f: F, - ) -> R - where - F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, - { - match self.len() { - 0 => ().with_normalized(env, from, to, fc, f), - 1 => self.get(0).with_normalized(env, from, to, fc, f), - _ => to.with_address_ref(env, |to_addr| { - let fc_conv = fc.convert_to_multi_transfer_esdt_call(to_addr, self); - f(&from.resolve_address(env), &BigUint::zero(), &fc_conv) - }), - } - } -} - -impl TxPaymentNormalize for EgldOrEsdtTokenPayment -where - Env: TxEnv, - From: TxFrom, - To: TxToSpecified, -{ - fn with_normalized( - self, - env: &Env, - from: &From, - to: To, - fc: FunctionCall, - f: F, - ) -> R - where - F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, - { - self.map_egld_or_esdt( - (to, fc, f), - |(to, fc, f), amount| Egld(amount).with_normalized(env, from, to, fc, f), - |(to, fc, f), esdt_payment| esdt_payment.with_normalized(env, from, to, fc, f), - ) - } -} - -impl TxPaymentNormalize for EgldOrMultiEsdtPayment -where - Env: TxEnv, - From: TxFrom, - To: TxToSpecified, -{ - fn with_normalized( - self, - env: &Env, - from: &From, - to: To, - fc: FunctionCall, - f: F, - ) -> R - where - F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, - { - match self { - EgldOrMultiEsdtPayment::Egld(egld_amount) => { - Egld(egld_amount).with_normalized(env, from, to, fc, f) - }, - EgldOrMultiEsdtPayment::MultiEsdt(multi_esdt_payment) => { - multi_esdt_payment.with_normalized(env, from, to, fc, f) - }, - } - } -} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_other.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_other.rs index 0c8bf7772b..5a28d80902 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_other.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_other.rs @@ -2,6 +2,7 @@ use crate::{ contract_base::SendRawWrapper, types::{ BigUint, Egld, EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, ManagedAddress, ManagedVec, + TxFrom, TxToSpecified, }, }; @@ -29,6 +30,26 @@ where ) } + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, + { + self.map_egld_or_esdt( + (to, fc, f), + |(to, fc, f), amount| Egld(amount).with_normalized(env, from, to, fc, f), + |(to, fc, f), esdt_payment| esdt_payment.with_normalized(env, from, to, fc, f), + ) + } + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { self.map_egld_or_esdt( (), @@ -63,6 +84,29 @@ where } } + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, + { + match self { + EgldOrMultiEsdtPayment::Egld(egld_amount) => { + Egld(egld_amount).with_normalized(env, from, to, fc, f) + }, + EgldOrMultiEsdtPayment::MultiEsdt(multi_esdt_payment) => { + multi_esdt_payment.with_normalized(env, from, to, fc, f) + }, + } + } + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { match self { EgldOrMultiEsdtPayment::Egld(egld_amount) => { diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt.rs index 7651351db8..f2fdf5aacb 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt.rs @@ -1,6 +1,9 @@ use crate::{ contract_base::SendRawWrapper, - types::{BigUint, EsdtTokenPayment, ManagedAddress, ManagedVec, MultiEsdtPayment}, + types::{ + BigUint, EsdtTokenPayment, ManagedAddress, ManagedVec, MultiEsdtPayment, TxFrom, + TxToSpecified, + }, }; use super::{AnnotatedEgldPayment, FullPaymentData, FunctionCall, TxEgldValue, TxEnv, TxPayment}; @@ -23,6 +26,30 @@ where MultiEsdtPayment::from_single_item(self).perform_transfer_execute(env, to, gas_limit, fc); } + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, + { + to.with_address_ref(env, |to_addr| { + if self.token_nonce == 0 { + let fc_conv = fc.convert_to_single_transfer_fungible_call(&self); + f(to_addr, &BigUint::zero(), &fc_conv) + } else { + let fc_conv = fc.convert_to_single_transfer_nft_call(to_addr, &self); + f(&from.resolve_address(env), &BigUint::zero(), &fc_conv) + } + }) + } + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { FullPaymentData { egld: None,