diff --git a/chain/vm/src/host/context/managed_type_container/tx_managed_buffer.rs b/chain/vm/src/host/context/managed_type_container/tx_managed_buffer.rs index 5f8aeccf4d..9a38c14dde 100644 --- a/chain/vm/src/host/context/managed_type_container/tx_managed_buffer.rs +++ b/chain/vm/src/host/context/managed_type_container/tx_managed_buffer.rs @@ -97,7 +97,7 @@ impl ManagedTypeContainer { let mut num_bytes_copied = 0; let data = self.mb_get(source_handle); assert!( - data.len() % 4 == 0, + data.len().is_multiple_of(4), "malformed ManagedVec data" ); for chunk in data.chunks(4) { @@ -134,7 +134,7 @@ impl ManagedTypeContainer { let mut num_bytes_copied = 0; let data = self.mb_get(source_handle); assert!( - data.len() % 16 == 0, + data.len().is_multiple_of(16), "malformed ManagedVec data" ); for chunk in data.chunks(16) { diff --git a/contracts/core/price-aggregator/src/median.rs b/contracts/core/price-aggregator/src/median.rs index 53227bc9d7..90021c5a2a 100644 --- a/contracts/core/price-aggregator/src/median.rs +++ b/contracts/core/price-aggregator/src/median.rs @@ -11,7 +11,7 @@ pub fn calculate( list.sort_unstable(); let len = list.len(); let middle_index = len / 2; - if len % 2 == 0 { + if len.is_multiple_of(2) { let median1 = list.get(middle_index - 1).ok_or("median1 invalid index")?; let median2 = list.get(middle_index).ok_or("median2 invalid index")?; Result::Ok(Some((median1.clone() + median2.clone()) / 2u64)) diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_async_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_async_legacy.rs index 3fc4e49cd4..ebc4cc1165 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_async_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_async_legacy.rs @@ -57,7 +57,7 @@ pub trait ForwarderAsyncCallModule { #[endpoint] #[payable("*")] fn forward_async_accept_funds(&self, to: ManagedAddress) { - let payment = self.call_value().single_optional(); + let payment = self.call_value().all(); self.vault_proxy() .contract(to) .accept_funds() diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs index d957ddac9b..1397637c7a 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs @@ -10,12 +10,12 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let opt_payment = self.call_value().single_optional(); + let payment = self.call_value().all(); self.tx() .to(to) .raw_call(endpoint_name) .arguments_raw(args.to_arg_buffer()) - .payment(opt_payment) + .payment(payment) .async_call_and_exit() } diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_call_async.rs b/contracts/feature-tests/composability/forwarder/src/fwd_call_async.rs index 6f4fadaaeb..d68e8ab88c 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_call_async.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_async.rs @@ -49,7 +49,7 @@ pub trait ForwarderAsyncCallModule: common::CommonModule { #[endpoint] #[payable("*")] fn forward_async_accept_funds(&self, to: ManagedAddress) { - let payment = self.call_value().single_optional(); + let payment = self.call_value().all(); self.tx() .to(&to) .typed(vault_proxy::VaultProxy) @@ -119,7 +119,7 @@ pub trait ForwarderAsyncCallModule: common::CommonModule { .to(&to) .typed(vault_proxy::VaultProxy) .reject_funds() - .payment(payment) + .payment(MultiTransfer(payment)) .callback(self.callbacks().retrieve_funds_callback()) .async_call_and_exit() } diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_call_promises.rs b/contracts/feature-tests/composability/forwarder/src/fwd_call_promises.rs index cf7cb71b1f..fac79cc9b0 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_call_promises.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_promises.rs @@ -10,7 +10,7 @@ pub trait CallPromisesModule: common::CommonModule { #[endpoint] #[payable("*")] fn forward_promise_accept_funds(&self, to: ManagedAddress) { - let payment = self.call_value().single_optional(); + let payment = self.call_value().all(); let gas_limit = self.blockchain().get_gas_left() / 2; self.tx() diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs b/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs index faae6c4d8d..f9ffcfb82a 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs @@ -61,7 +61,7 @@ pub trait ForwarderSyncCallModule { #[endpoint] #[payable("*")] fn forward_sync_accept_funds(&self, to: ManagedAddress) { - let payment = self.call_value().single_optional(); + let payment = self.call_value().all(); let half_gas = self.blockchain().get_gas_left() / 2; let result = self @@ -168,7 +168,7 @@ pub trait ForwarderSyncCallModule { #[endpoint] #[payable("*")] fn forward_sync_accept_funds_then_read(&self, to: ManagedAddress) -> usize { - let payment = self.call_value().single_optional(); + let payment = self.call_value().all(); self.tx() .to(&to) .typed(vault_proxy::VaultProxy) diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_call_transf_exec.rs b/contracts/feature-tests/composability/forwarder/src/fwd_call_transf_exec.rs index 4e6d4c038e..3f3269d074 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_call_transf_exec.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_transf_exec.rs @@ -9,7 +9,7 @@ pub trait ForwarderTransferExecuteModule { #[endpoint] #[payable] fn forward_transf_exec_accept_funds(&self, to: ManagedAddress) { - let payment = self.call_value().single_optional(); + let payment = self.call_value().all(); self.tx() .to(&to) .typed(vault_proxy::VaultProxy) diff --git a/framework/base/src/types/interaction/tx_payment.rs b/framework/base/src/types/interaction/tx_payment.rs index fd349abfd5..d9e3467825 100644 --- a/framework/base/src/types/interaction/tx_payment.rs +++ b/framework/base/src/types/interaction/tx_payment.rs @@ -7,16 +7,17 @@ mod tx_payment_egld_or_multi_esdt_refs; mod tx_payment_egld_value; mod tx_payment_multi_egld_or_esdt; mod tx_payment_multi_esdt; +mod tx_payment_multi_transfer_marker; mod tx_payment_none; mod tx_payment_not_payable; mod tx_payment_payment; mod tx_payment_payment_option; mod tx_payment_payment_ref; mod tx_payment_payment_refs; -mod tx_payment_payment_vec; mod tx_payment_single_esdt; mod tx_payment_single_esdt_ref; mod tx_payment_single_esdt_triple; +mod tx_payment_vec_ref; pub use test_esdt_transfer::TestEsdtTransfer; pub use tx_payment_egld::{Egld, EgldPayment}; diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_multi_transfer_marker.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_multi_transfer_marker.rs new file mode 100644 index 0000000000..d33dc00848 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_multi_transfer_marker.rs @@ -0,0 +1,80 @@ +use crate::{ + contract_base::{SendRawWrapper, TransferExecuteFailed}, + types::{BigUint, ManagedAddress, MultiTransfer, PaymentVec, TxFrom, TxToSpecified}, +}; + +use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; + +impl TxPayment for MultiTransfer

+where + Env: TxEnv, + P: AsRef>, +{ + fn is_no_payment(&self, _env: &Env) -> bool { + let pv = self.0.as_ref(); + pv.is_empty() + } + + fn perform_transfer_execute_fallible( + self, + _env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) -> Result<(), TransferExecuteFailed> { + let pv = self.0.as_ref(); + SendRawWrapper::::new().multi_egld_or_esdt_transfer_execute_fallible( + to, + pv.as_multi_egld_or_esdt_payment(), + gas_limit, + &fc.function_name, + &fc.arg_buffer, + ) + } + + fn perform_transfer_execute_legacy( + self, + _env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + let pv = self.0.as_ref(); + SendRawWrapper::::new().multi_egld_or_esdt_transfer_execute( + to, + pv.as_multi_egld_or_esdt_payment(), + gas_limit, + &fc.function_name, + &fc.arg_buffer, + ); + } + + 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, + { + let pv = self.0.as_ref(); + to.with_address_ref(env, |to_addr| { + let fc_conv = + fc.convert_to_multi_transfer_esdt_call(to_addr, pv.as_multi_egld_or_esdt_payment()); + f(&from.resolve_address(env), &*BigUint::zero_ref(), fc_conv) + }) + } + + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { + let pv = self.0.as_ref(); + FullPaymentData { + egld: None, + multi_esdt: pv.as_multi_egld_or_esdt_payment().clone(), + } + } +} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_payment_ref.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_payment_ref.rs index fec2245ed3..19e52e53d0 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_payment_ref.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_payment_ref.rs @@ -5,108 +5,66 @@ use crate::{ use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; -impl TxPayment for &Payment -where - Env: TxEnv, -{ - #[inline] - fn is_no_payment(&self, _env: &Env) -> bool { - // amount is NonZeroBigUint - false - } +macro_rules! impl_txpayment_for_payment_ref { + ($ty:ty) => { + impl TxPayment for $ty + where + Env: TxEnv, + { + #[inline] + fn is_no_payment(&self, _env: &Env) -> bool { + // amount is NonZeroBigUint + false + } - fn perform_transfer_execute_fallible( - self, - env: &Env, - to: &ManagedAddress, - gas_limit: u64, - fc: FunctionCall, - ) -> Result<(), TransferExecuteFailed> { - self.as_refs() - .perform_transfer_execute_fallible(env, to, gas_limit, fc) - } + fn perform_transfer_execute_fallible( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) -> Result<(), TransferExecuteFailed> { + self.as_refs() + .perform_transfer_execute_fallible(env, to, gas_limit, fc) + } - fn perform_transfer_execute_legacy( - self, - env: &Env, - to: &ManagedAddress, - gas_limit: u64, - fc: FunctionCall, - ) { - self.as_refs() - .perform_transfer_execute_legacy(env, to, gas_limit, fc) - } + fn perform_transfer_execute_legacy( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + self.as_refs() + .perform_transfer_execute_legacy(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.as_refs().with_normalized(env, from, to, fc, f) - } + 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.as_refs().with_normalized(env, from, to, fc, f) + } - fn into_full_payment_data(self, env: &Env) -> FullPaymentData { - self.as_refs().into_full_payment_data(env) - } + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + self.as_refs().into_full_payment_data(env) + } + } + }; } -impl TxPayment for Ref<'_, Payment> -where - Env: TxEnv, -{ - #[inline] - fn is_no_payment(&self, _env: &Env) -> bool { - // amount is NonZeroBigUint - false - } - - fn perform_transfer_execute_fallible( - self, - env: &Env, - to: &ManagedAddress, - gas_limit: u64, - fc: FunctionCall, - ) -> Result<(), TransferExecuteFailed> { - self.as_refs() - .perform_transfer_execute_fallible(env, to, gas_limit, fc) - } - - fn perform_transfer_execute_legacy( - self, - env: &Env, - to: &ManagedAddress, - gas_limit: u64, - fc: FunctionCall, - ) { - self.as_refs() - .perform_transfer_execute_legacy(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.as_refs().with_normalized(env, from, to, fc, f) - } - - fn into_full_payment_data(self, env: &Env) -> FullPaymentData { - self.as_refs().into_full_payment_data(env) - } -} +impl_txpayment_for_payment_ref!(&Payment); +impl_txpayment_for_payment_ref!(Ref<'_, Payment>); diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_payment_vec.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_payment_vec.rs deleted file mode 100644 index 1dd59bfbd5..0000000000 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_payment_vec.rs +++ /dev/null @@ -1,187 +0,0 @@ -use core::ops::Deref; - -use crate::{ - contract_base::{SendRawWrapper, TransferExecuteFailed}, - types::{BigUint, ManagedAddress, ManagedRef, PaymentVec, TxFrom, TxToSpecified}, -}; - -use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; - -impl TxPayment for &PaymentVec -where - Env: TxEnv, -{ - fn is_no_payment(&self, _env: &Env) -> bool { - self.is_empty() - } - - fn perform_transfer_execute_fallible( - self, - _env: &Env, - to: &ManagedAddress, - gas_limit: u64, - fc: FunctionCall, - ) -> Result<(), TransferExecuteFailed> { - SendRawWrapper::::new().multi_egld_or_esdt_transfer_execute_fallible( - to, - self.as_multi_egld_or_esdt_payment(), - gas_limit, - &fc.function_name, - &fc.arg_buffer, - ) - } - - fn perform_transfer_execute_legacy( - self, - _env: &Env, - to: &ManagedAddress, - gas_limit: u64, - fc: FunctionCall, - ) { - SendRawWrapper::::new().multi_egld_or_esdt_transfer_execute( - to, - self.as_multi_egld_or_esdt_payment(), - gas_limit, - &fc.function_name, - &fc.arg_buffer, - ); - } - - 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| { - let fc_conv = fc - .convert_to_multi_transfer_esdt_call(to_addr, self.as_multi_egld_or_esdt_payment()); - f(&from.resolve_address(env), &*BigUint::zero_ref(), fc_conv) - }) - } - - fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { - FullPaymentData { - egld: None, - multi_esdt: self.as_multi_egld_or_esdt_payment().clone(), - } - } -} - -impl TxPayment for ManagedRef<'_, Env::Api, PaymentVec> -where - Env: TxEnv, -{ - #[inline] - fn is_no_payment(&self, _env: &Env) -> bool { - self.deref().is_empty() - } - - #[inline] - fn perform_transfer_execute_fallible( - self, - env: &Env, - to: &ManagedAddress, - gas_limit: u64, - fc: FunctionCall, - ) -> Result<(), TransferExecuteFailed> { - self.deref() - .perform_transfer_execute_fallible(env, to, gas_limit, fc) - } - - #[inline] - fn perform_transfer_execute_legacy( - self, - env: &Env, - to: &ManagedAddress, - gas_limit: u64, - fc: FunctionCall, - ) { - self.deref() - .perform_transfer_execute_legacy(env, to, gas_limit, fc) - } - - #[inline] - 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.deref().with_normalized(env, from, to, fc, f) - } - - fn into_full_payment_data(self, env: &Env) -> FullPaymentData { - self.deref().into_full_payment_data(env) - } -} - -impl TxPayment for PaymentVec -where - Env: TxEnv, -{ - #[inline] - fn is_no_payment(&self, _env: &Env) -> bool { - self.is_empty() - } - - #[inline] - fn perform_transfer_execute_fallible( - self, - env: &Env, - to: &ManagedAddress, - gas_limit: u64, - fc: FunctionCall, - ) -> Result<(), TransferExecuteFailed> { - (&self).perform_transfer_execute_fallible(env, to, gas_limit, fc) - } - - #[inline] - fn perform_transfer_execute_legacy( - self, - env: &Env, - to: &ManagedAddress, - gas_limit: u64, - fc: FunctionCall, - ) { - (&self).perform_transfer_execute_legacy(env, to, gas_limit, fc) - } - - #[inline] - 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, - multi_esdt: self.into_multi_egld_or_esdt_payment(), - } - } -} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_vec_ref.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_vec_ref.rs new file mode 100644 index 0000000000..71e059c235 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_vec_ref.rs @@ -0,0 +1,81 @@ +use crate::{ + contract_base::TransferExecuteFailed, + types::{BigUint, ManagedAddress, MultiTransfer, PaymentVec, TxFrom, TxToSpecified}, +}; + +use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; + +impl TxPayment for P +where + Env: TxEnv, + P: AsRef>, +{ + fn is_no_payment(&self, _env: &Env) -> bool { + let pv = self.as_ref(); + pv.is_empty() + } + + fn perform_transfer_execute_fallible( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) -> Result<(), TransferExecuteFailed> { + let pv = self.as_ref(); + match pv.len() { + 0 => ().perform_transfer_execute_fallible(env, to, gas_limit, fc), + 1 => pv + .get(0) + .perform_transfer_execute_fallible(env, to, gas_limit, fc), + _ => MultiTransfer(pv).perform_transfer_execute_fallible(env, to, gas_limit, fc), + } + } + + fn perform_transfer_execute_legacy( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + let pv = self.as_ref(); + match pv.len() { + 0 => ().perform_transfer_execute_legacy(env, to, gas_limit, fc), + 1 => pv + .get(0) + .perform_transfer_execute_legacy(env, to, gas_limit, fc), + _ => MultiTransfer(pv).perform_transfer_execute_legacy(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, + { + let pv = self.as_ref(); + match pv.len() { + 0 => ().with_normalized(env, from, to, fc, f), + 1 => pv.get(0).with_normalized(env, from, to, fc, f), + _ => MultiTransfer(pv).with_normalized(env, from, to, fc, f), + } + } + + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + let pv = self.as_ref(); + match pv.len() { + 0 => ().into_full_payment_data(env), + 1 => pv.get(0).into_full_payment_data(env), + _ => MultiTransfer(pv).into_full_payment_data(env), + } + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_ref.rs b/framework/base/src/types/managed/wrapped/managed_ref.rs index bd737f358e..2039e971e1 100644 --- a/framework/base/src/types/managed/wrapped/managed_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_ref.rs @@ -99,6 +99,16 @@ where } } +impl AsRef for ManagedRef<'_, M, T> +where + M: ManagedTypeApi, + T: ManagedType, +{ + fn as_ref(&self) -> &T { + self.deref() + } +} + impl<'a, M, T> From<&'a T> for ManagedRef<'a, M, T> where M: ManagedTypeApi, diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 2237d9c1af..30a0daf093 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -125,6 +125,17 @@ where } } +impl AsRef> for ManagedVec +where + M: ManagedTypeApi, + T: ManagedVecItem, +{ + #[inline] + fn as_ref(&self) -> &ManagedVec { + self + } +} + impl ManagedVec where M: ManagedTypeApi, diff --git a/framework/base/src/types/managed/wrapped/managed_vec_ref.rs b/framework/base/src/types/managed/wrapped/managed_vec_ref.rs index 057854ffe5..76ff779be6 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref.rs @@ -66,6 +66,15 @@ where } } +impl AsRef for Ref<'_, T> +where + T: ManagedVecItem, +{ + fn as_ref(&self) -> &T { + self.deref() + } +} + impl Debug for Ref<'_, T> where T: ManagedVecItem + Debug, diff --git a/framework/base/src/types/managed/wrapped/token.rs b/framework/base/src/types/managed/wrapped/token.rs index 0c3dfd9b0f..7029b0b905 100644 --- a/framework/base/src/types/managed/wrapped/token.rs +++ b/framework/base/src/types/managed/wrapped/token.rs @@ -6,6 +6,7 @@ mod esdt_token_data; mod esdt_token_identifier; mod esdt_token_payment; mod multi_egld_or_esdt_token_payment; +mod multi_transfer_marker; mod payment; mod payment_refs; mod payment_vec; @@ -19,6 +20,7 @@ pub use esdt_token_data::EsdtTokenData; pub use esdt_token_identifier::{EsdtTokenIdentifier, TokenIdentifier}; pub use esdt_token_payment::{EsdtTokenPayment, EsdtTokenPaymentRefs, MultiEsdtPayment}; pub use multi_egld_or_esdt_token_payment::MultiEgldOrEsdtPayment; +pub use multi_transfer_marker::MultiTransfer; pub use payment::Payment; pub use payment_refs::PaymentRefs; pub use payment_vec::PaymentVec; diff --git a/framework/base/src/types/managed/wrapped/token/multi_transfer_marker.rs b/framework/base/src/types/managed/wrapped/token/multi_transfer_marker.rs new file mode 100644 index 0000000000..b0fc751924 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/token/multi_transfer_marker.rs @@ -0,0 +1,7 @@ +/// A wrapper that forces payments to go via MultiESDTtransfer, even if it wouldn't be necessary, such as: +/// - Just EGLD +/// - Single fungible ESDT transfers, +/// - Single NFT transfers. +/// +/// This contrasts with unwrapped PaymentVec, tries to use the simplest possible transfer type. +pub struct MultiTransfer

(pub P); diff --git a/framework/base/src/types/managed/wrapped/token/payment.rs b/framework/base/src/types/managed/wrapped/token/payment.rs index 4a94f63640..45c6b873e6 100644 --- a/framework/base/src/types/managed/wrapped/token/payment.rs +++ b/framework/base/src/types/managed/wrapped/token/payment.rs @@ -109,6 +109,16 @@ impl Payment { } } +impl AsRef> for &Payment +where + M: ManagedTypeApi, +{ + #[inline] + fn as_ref(&self) -> &Payment { + self + } +} + impl From<(TokenId, u64, NonZeroBigUint)> for Payment { #[inline] fn from(value: (TokenId, u64, NonZeroBigUint)) -> Self { diff --git a/framework/meta-lib/src/cargo_toml/cargo_toml_contents.rs b/framework/meta-lib/src/cargo_toml/cargo_toml_contents.rs index 161c0783c0..b14a7eb2cf 100644 --- a/framework/meta-lib/src/cargo_toml/cargo_toml_contents.rs +++ b/framework/meta-lib/src/cargo_toml/cargo_toml_contents.rs @@ -28,7 +28,7 @@ const AUTO_GENERATED: &str = "# Code generated by the multiversx-sc build system /// /// - Currently contains a raw toml tree, but in principle it could also work with a cargo_toml::Manifest. /// - It keeps an ordered representation, thanks to the `toml` `preserve_order` feature. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct CargoTomlContents { pub path: PathBuf, pub toml_value: toml::Table, @@ -59,11 +59,7 @@ impl CargoTomlContents { } pub fn new() -> Self { - CargoTomlContents { - path: PathBuf::new(), - toml_value: Table::new(), - prepend_auto_generated_comment: false, - } + CargoTomlContents::default() } pub fn save_to_file>(&self, path: P) { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 4f3e8c5218..73328e053b 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.89" +channel = "1.90" diff --git a/sdk/scenario-format/src/value_interpreter/parse_num.rs b/sdk/scenario-format/src/value_interpreter/parse_num.rs index 2f23c2bc7e..0d63973fa2 100644 --- a/sdk/scenario-format/src/value_interpreter/parse_num.rs +++ b/sdk/scenario-format/src/value_interpreter/parse_num.rs @@ -110,7 +110,7 @@ fn parse_unsigned(s: &str) -> Vec { let clean = s.replace(&['_', ','][..], ""); if clean.starts_with("0x") || clean.starts_with("0X") { let clean = &clean[2..]; - return if clean.len() % 2 == 0 { + return if clean.len().is_multiple_of(2) { hex::decode(clean).unwrap() } else { let even_bytes = format!("0{clean}");