From abe973a26b7e72aad1537628cb84621b1d961d56 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 18 Jul 2024 21:08:19 +0300 Subject: [PATCH 001/133] integration of executor v1.7.next1 --- Cargo.lock | 75 ++++++++++++++++---------------- framework/scenario/Cargo.toml | 4 +- vm/Cargo.toml | 4 +- vm/src/vm_hooks/vh_dispatcher.rs | 49 +++++++++++++++++++++ 4 files changed, 92 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 815470d026..5a348bfd06 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -378,15 +378,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "cc" -version = "1.0.104" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" +checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" [[package]] name = "cfg-if" @@ -431,9 +431,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.8" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" dependencies = [ "clap_builder", "clap_derive", @@ -441,9 +441,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.8" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" dependencies = [ "anstream", "anstyle", @@ -1378,9 +1378,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http", @@ -1413,9 +1413,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", @@ -1916,8 +1916,7 @@ dependencies = [ [[package]] name = "multiversx-chain-vm-executor" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b59072fa0624b55ae5ae3fa6bfa91515bbeb4ac440214bc4a509e2c8806d6e9f" +source = "git+https://github.com/multiversx/mx-vm-executor-rs?branch=rc/v1.7.next1#95acf80fb611fb51a8b7e20f5e7086e4aae68539" [[package]] name = "multiversx-price-aggregator-sc" @@ -2718,9 +2717,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ "bitflags 2.6.0", ] @@ -2913,9 +2912,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.10" +version = "0.23.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" +checksum = "4828ea528154ae444e5a642dbb7d5623354030dc9822b83fd9bb79683c7399d0" dependencies = [ "once_cell", "rustls-pki-types", @@ -3016,9 +3015,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.6.0", "core-foundation", @@ -3029,9 +3028,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -3078,18 +3077,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", @@ -3349,18 +3348,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", @@ -3369,9 +3368,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6b6a2fb3a985e99cebfaefa9faa3024743da73304ca1c683a36429613d3d22" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -3400,9 +3399,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.38.0" +version = "1.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" dependencies = [ "backtrace", "bytes", @@ -3464,9 +3463,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" dependencies = [ "indexmap", "serde", @@ -3486,9 +3485,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.14" +version = "0.22.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" dependencies = [ "indexmap", "serde", diff --git a/framework/scenario/Cargo.toml b/framework/scenario/Cargo.toml index e58e6d9255..25e43afdef 100644 --- a/framework/scenario/Cargo.toml +++ b/framework/scenario/Cargo.toml @@ -50,7 +50,9 @@ version = "0.22.3" path = "../../sdk/scenario-format" [dependencies.multiversx-chain-vm-executor] -version = "0.2.0" +# version = "0.2.0" +git = "https://github.com/multiversx/mx-vm-executor-rs" +branch = "rc/v1.7.next1" [dependencies.multiversx-chain-vm] version = "=0.9.0" diff --git a/vm/Cargo.toml b/vm/Cargo.toml index baf8ec3894..2da432d240 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -35,4 +35,6 @@ rand_seeder = { version= "0.2.2", optional = true } ed25519-dalek = { version = "1.0.1" , optional = true } [dependencies.multiversx-chain-vm-executor] -version = "0.2.0" +# version = "0.2.0" +git = "https://github.com/multiversx/mx-vm-executor-rs" +branch = "rc/v1.7.next1" diff --git a/vm/src/vm_hooks/vh_dispatcher.rs b/vm/src/vm_hooks/vh_dispatcher.rs index 0dbfc54051..46c5153819 100644 --- a/vm/src/vm_hooks/vh_dispatcher.rs +++ b/vm/src/vm_hooks/vh_dispatcher.rs @@ -1859,4 +1859,53 @@ impl VMHooks for VMHooksDispatcher { ) -> i32 { panic!("Unavailable: elliptic_curve_get_values") } + + fn is_reserved_function_name(&self, name_handle: i32) -> i32 { + panic!("Unavailable: is_reserved_function_name") + } + + fn managed_get_original_caller_addr(&self, destination_handle: i32) { + panic!("Unavailable: managed_get_original_caller_addr") + } + + fn managed_get_relayer_addr(&self, destination_handle: i32) { + panic!("Unavailable: managed_get_relayer_addr") + } + + fn managed_multi_transfer_esdt_nft_execute_by_user( + &self, + user_handle: i32, + dst_handle: i32, + token_transfers_handle: i32, + gas_limit: i64, + function_handle: i32, + arguments_handle: i32, + ) -> i32 { + panic!("Unavailable: managed_multi_transfer_esdt_nft_execute_by_user") + } + + fn managed_verify_secp256r1( + &self, + key_handle: i32, + message_handle: i32, + sig_handle: i32, + ) -> i32 { + panic!("Unavailable: managed_verify_secp256r1") + } + fn managed_verify_blssignature_share( + &self, + key_handle: i32, + message_handle: i32, + sig_handle: i32, + ) -> i32 { + panic!("Unavailable: managed_verify_blssignature_share") + } + fn managed_verify_blsaggregated_signature( + &self, + key_handle: i32, + message_handle: i32, + sig_handle: i32, + ) -> i32 { + panic!("Unavailable: managed_verify_blsaggregated_signature") + } } From 36aedd479985f5e94d11fad350ad995415b9ed3c Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 8 Nov 2024 20:54:42 +0200 Subject: [PATCH 002/133] ManagedRefMut implementation --- framework/base/src/storage/storage_key.rs | 4 + .../types/interaction/managed_arg_buffer.rs | 4 + .../base/src/types/managed/basic/big_float.rs | 4 + .../base/src/types/managed/basic/big_int.rs | 5 + .../src/types/managed/basic/elliptic_curve.rs | 4 + .../src/types/managed/basic/managed_buffer.rs | 8 +- .../src/types/managed/basic/managed_map.rs | 4 + .../src/types/managed/managed_type_trait.rs | 2 + .../multi_value/multi_value_managed_vec.rs | 4 + .../src/types/managed/wrapped/big_uint.rs | 4 + .../types/managed/wrapped/managed_address.rs | 4 + .../managed/wrapped/managed_byte_array.rs | 4 + .../types/managed/wrapped/managed_ref_mut.rs | 174 ++++++++++++++++++ .../src/types/managed/wrapped/managed_vec.rs | 7 +- .../types/managed/wrapped/managed_vec_ref.rs | 18 +- .../base/src/types/managed/wrapped/mod.rs | 2 + .../types/managed/wrapped/token_identifier.rs | 4 + 17 files changed, 249 insertions(+), 7 deletions(-) create mode 100644 framework/base/src/types/managed/wrapped/managed_ref_mut.rs diff --git a/framework/base/src/storage/storage_key.rs b/framework/base/src/storage/storage_key.rs index b56358218b..f692dd5266 100644 --- a/framework/base/src/storage/storage_key.rs +++ b/framework/base/src/storage/storage_key.rs @@ -35,6 +35,10 @@ where fn transmute_from_handle_ref(handle_ref: &A::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut A::ManagedBufferHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl StorageKey diff --git a/framework/base/src/types/interaction/managed_arg_buffer.rs b/framework/base/src/types/interaction/managed_arg_buffer.rs index c6dae76afd..bd98c40931 100644 --- a/framework/base/src/types/interaction/managed_arg_buffer.rs +++ b/framework/base/src/types/interaction/managed_arg_buffer.rs @@ -46,6 +46,10 @@ where fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::ManagedBufferHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl ManagedArgBuffer diff --git a/framework/base/src/types/managed/basic/big_float.rs b/framework/base/src/types/managed/basic/big_float.rs index 54850a1672..802d582e94 100644 --- a/framework/base/src/types/managed/basic/big_float.rs +++ b/framework/base/src/types/managed/basic/big_float.rs @@ -38,6 +38,10 @@ impl ManagedType for BigFloat { fn transmute_from_handle_ref(handle_ref: &M::BigFloatHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::BigFloatHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl From<&ManagedBuffer> for BigFloat { diff --git a/framework/base/src/types/managed/basic/big_int.rs b/framework/base/src/types/managed/basic/big_int.rs index c705511f56..cb52117c32 100644 --- a/framework/base/src/types/managed/basic/big_int.rs +++ b/framework/base/src/types/managed/basic/big_int.rs @@ -39,6 +39,11 @@ impl ManagedType for BigInt { fn transmute_from_handle_ref(handle_ref: &M::BigIntHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::BigIntHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } + } impl Default for BigInt { diff --git a/framework/base/src/types/managed/basic/elliptic_curve.rs b/framework/base/src/types/managed/basic/elliptic_curve.rs index 99189d06c5..8c110f6459 100644 --- a/framework/base/src/types/managed/basic/elliptic_curve.rs +++ b/framework/base/src/types/managed/basic/elliptic_curve.rs @@ -46,6 +46,10 @@ impl ManagedType for EllipticCurve { fn transmute_from_handle_ref(handle_ref: &M::EllipticCurveHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::EllipticCurveHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl EllipticCurve { diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index de2dc63bb8..34ba82da14 100644 --- a/framework/base/src/types/managed/basic/managed_buffer.rs +++ b/framework/base/src/types/managed/basic/managed_buffer.rs @@ -13,7 +13,9 @@ use crate::{ hex_util::encode_bytes_as_hex, FormatBuffer, FormatByteReceiver, SCBinary, SCDisplay, SCLowerHex, }, - types::{heap::BoxedBytes, ManagedBufferCachedBuilder, ManagedType, StaticBufferRef}, + types::{ + heap::BoxedBytes, ManagedBufferCachedBuilder, ManagedType, StaticBufferRef, + }, }; /// A byte buffer managed by an external API. @@ -37,6 +39,10 @@ impl ManagedType for ManagedBuffer { fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::ManagedBufferHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl ManagedBuffer { diff --git a/framework/base/src/types/managed/basic/managed_map.rs b/framework/base/src/types/managed/basic/managed_map.rs index 1f0c0be867..ed39011f8d 100644 --- a/framework/base/src/types/managed/basic/managed_map.rs +++ b/framework/base/src/types/managed/basic/managed_map.rs @@ -26,6 +26,10 @@ impl ManagedType for ManagedMap { fn transmute_from_handle_ref(handle_ref: &M::ManagedMapHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::ManagedMapHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl ManagedMap { diff --git a/framework/base/src/types/managed/managed_type_trait.rs b/framework/base/src/types/managed/managed_type_trait.rs index ae9b48e4d0..e7b97e2ab6 100644 --- a/framework/base/src/types/managed/managed_type_trait.rs +++ b/framework/base/src/types/managed/managed_type_trait.rs @@ -26,6 +26,8 @@ pub trait ManagedType: Sized { /// For types that just wrap another managed type it is easier, call for the wrapped object. fn transmute_from_handle_ref(handle_ref: &Self::OwnHandle) -> &Self; + fn transmute_from_handle_ref_mut(handle_ref: &mut Self::OwnHandle) -> &mut Self; + fn as_ref(&self) -> ManagedRef<'_, M, Self> { ManagedRef::new(self) } diff --git a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs index a168711af1..e628ba8421 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs @@ -57,6 +57,10 @@ where fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::ManagedBufferHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl MultiValueManagedVec diff --git a/framework/base/src/types/managed/wrapped/big_uint.rs b/framework/base/src/types/managed/wrapped/big_uint.rs index 615d790480..dfba440073 100644 --- a/framework/base/src/types/managed/wrapped/big_uint.rs +++ b/framework/base/src/types/managed/wrapped/big_uint.rs @@ -39,6 +39,10 @@ impl ManagedType for BigUint { fn transmute_from_handle_ref(handle_ref: &M::BigIntHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::BigIntHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl From for BigUint { diff --git a/framework/base/src/types/managed/wrapped/managed_address.rs b/framework/base/src/types/managed/wrapped/managed_address.rs index a90482fb04..18473419e4 100644 --- a/framework/base/src/types/managed/wrapped/managed_address.rs +++ b/framework/base/src/types/managed/wrapped/managed_address.rs @@ -146,6 +146,10 @@ where fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::ManagedBufferHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl Default for ManagedAddress diff --git a/framework/base/src/types/managed/wrapped/managed_byte_array.rs b/framework/base/src/types/managed/wrapped/managed_byte_array.rs index 83e95d332c..9d7b15d2b7 100644 --- a/framework/base/src/types/managed/wrapped/managed_byte_array.rs +++ b/framework/base/src/types/managed/wrapped/managed_byte_array.rs @@ -48,6 +48,10 @@ where fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::ManagedBufferHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl Default for ManagedByteArray diff --git a/framework/base/src/types/managed/wrapped/managed_ref_mut.rs b/framework/base/src/types/managed/wrapped/managed_ref_mut.rs new file mode 100644 index 0000000000..81315b89b2 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_ref_mut.rs @@ -0,0 +1,174 @@ +use core::ops::DerefMut; +use core::{borrow::Borrow, marker::PhantomData, ops::Deref}; + +use crate::codec::{ + EncodeErrorHandler, NestedEncode, NestedEncodeOutput, TopEncode, TopEncodeOutput, +}; + +use crate::{api::ManagedTypeApi, types::ManagedType}; + +/// A very efficient mutable reference to a managed type. +/// +/// It can be dereferenced mutably (DerefMut). +pub struct ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType, +{ + pub(super) _phantom_m: PhantomData, + pub(super) _phantom_t: PhantomData<&'a mut T>, + pub(super) handle: T::OwnHandle, +} + +impl<'a, M, T> ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType, +{ + pub fn new(value: &'a mut T) -> Self { + Self { + _phantom_m: PhantomData, + _phantom_t: PhantomData, + handle: value.get_handle(), + } + } + + /// Will completely disregard lifetimes, use with care. + #[doc(hidden)] + pub(crate) unsafe fn wrap_handle(handle: T::OwnHandle) -> Self { + Self { + _phantom_m: PhantomData, + _phantom_t: PhantomData, + handle, + } + } +} + +impl<'a, M, T> ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType + Clone, +{ + /// Syntactic sugar for dereferencing and cloning the object. + pub fn clone_value(&self) -> T { + self.deref().clone() + } +} + +impl<'a, M, T> Clone for ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType, +{ + #[inline] + fn clone(&self) -> Self { + Self { + _phantom_m: PhantomData, + _phantom_t: PhantomData, + handle: self.handle.clone(), + } + } +} + +impl<'a, M, T> Deref for ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType, +{ + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + Self::Target::transmute_from_handle_ref(&self.handle) + } +} + +impl<'a, M, T> DerefMut for ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + Self::Target::transmute_from_handle_ref_mut(&mut self.handle) + } +} + +impl<'a, M, T> Borrow for ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType, +{ + #[inline] + fn borrow(&self) -> &T { + self.deref() + } +} + +impl<'a, M, T> From<&'a mut T> for ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType, +{ + #[inline] + fn from(value_ref: &'a mut T) -> Self { + Self::new(value_ref) + } +} + +impl<'a, M, T> PartialEq for ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType + PartialEq, +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + self.deref() == other.deref() + } +} + +impl<'a, M, T> Eq for ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType + PartialEq, +{ +} + +impl<'a, M, T> TopEncode for ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType + TopEncode, +{ + #[inline] + fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> + where + O: TopEncodeOutput, + H: EncodeErrorHandler, + { + self.deref().top_encode_or_handle_err(output, h) + } +} + +impl<'a, M, T> NestedEncode for ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType + NestedEncode, +{ + #[inline] + fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr> + where + O: NestedEncodeOutput, + H: EncodeErrorHandler, + { + self.deref().dep_encode_or_handle_err(dest, h) + } +} + +impl<'a, M, T> core::fmt::Debug for ManagedRefMut<'a, M, T> +where + M: ManagedTypeApi, + T: ManagedType + core::fmt::Debug, +{ + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_tuple("ManagedRefMut").field(self.deref()).finish() + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 3e25360ea4..eb79ffebcd 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -59,6 +59,10 @@ where fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::ManagedBufferHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl ManagedVec @@ -233,7 +237,7 @@ where ManagedVec::new() }; - self.buffer = part_before.buffer; + *self = part_before; self.buffer.append(&part_after.buffer); } @@ -764,3 +768,4 @@ where } } } + 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 b69a124668..b339d1cdaf 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref.rs @@ -1,6 +1,6 @@ use crate::{ api::ManagedTypeApi, - types::{ManagedType, ManagedVec, ManagedVecItem}, + types::{ManagedVec, ManagedVecItem}, }; use core::{ marker::PhantomData, @@ -8,6 +8,8 @@ use core::{ ops::{Deref, DerefMut}, }; +use super::{ManagedRef, ManagedRefMut}; + pub struct ManagedVecRef<'a, M, T> where M: ManagedTypeApi, @@ -26,8 +28,10 @@ where T: ManagedVecItem, { #[inline] - fn wrap_as_managed_vec(managed_vec_handle: M::ManagedBufferHandle) -> ManagedVec { - ManagedVec::from_handle(managed_vec_handle) + unsafe fn wrap_as_managed_vec( + managed_vec_handle: M::ManagedBufferHandle, + ) -> ManagedRef<'static, M, ManagedVec> { + ManagedRef::wrap_handle(managed_vec_handle) } pub(super) fn new(managed_vec_handle: M::ManagedBufferHandle, item_index: usize) -> Self { @@ -50,8 +54,12 @@ where { fn drop(&mut self) { let item = unsafe { ManuallyDrop::take(&mut self.item) }; - let _ = - Self::wrap_as_managed_vec(self.managed_vec_handle.clone()).set(self.item_index, item); + unsafe { + let _ = + ManagedRefMut::>::wrap_handle(self.managed_vec_handle.clone()) + .set(self.item_index, item); + } + // core::mem::forget(item); } } diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped/mod.rs index 1874dc48b0..37849e0b6c 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -14,6 +14,7 @@ mod managed_byte_array; mod managed_decimal; mod managed_option; mod managed_ref; +mod managed_ref_mut; mod managed_vec; mod managed_vec_item; mod managed_vec_item_nested_tuple; @@ -43,6 +44,7 @@ pub use managed_decimal::{ }; pub use managed_option::ManagedOption; pub use managed_ref::ManagedRef; +pub use managed_ref_mut::ManagedRefMut; pub use managed_vec::ManagedVec; pub use managed_vec_item::ManagedVecItem; pub use managed_vec_item_nested_tuple::ManagedVecItemNestedTuple; diff --git a/framework/base/src/types/managed/wrapped/token_identifier.rs b/framework/base/src/types/managed/wrapped/token_identifier.rs index 1e66615199..69481772e0 100644 --- a/framework/base/src/types/managed/wrapped/token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/token_identifier.rs @@ -39,6 +39,10 @@ impl ManagedType for TokenIdentifier { fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::ManagedBufferHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl TokenIdentifier { From 59047ab10fc6be386f6e2b77cb451e4ddcad3ac6 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sat, 9 Nov 2024 03:26:03 +0200 Subject: [PATCH 003/133] ManagedType from_handle marked unsafe, refactoring --- .../basic-features/src/storage_direct_load.rs | 23 ++- contracts/modules/src/esdt.rs | 4 +- .../wrappers/blockchain_wrapper.rs | 139 +++++++++------- .../contract_base/wrappers/crypto_wrapper.rs | 49 +++--- .../wrappers/send_raw_wrapper.rs | 29 ++-- .../contract_base/wrappers/send_wrapper.rs | 5 +- .../wrappers/storage_raw_wrapper.rs | 3 +- framework/base/src/io/arg_de_input.rs | 37 +++-- framework/base/src/io/arg_nested_tuple.rs | 20 +-- framework/base/src/storage/storage_get.rs | 13 +- .../src/storage/storage_get_from_address.rs | 20 +-- framework/base/src/storage/storage_key.rs | 2 +- .../async_call_promises.rs | 10 +- .../contract_call_exec.rs | 10 +- .../types/interaction/managed_arg_buffer.rs | 2 +- .../types/interaction/markers/to_caller.rs | 10 +- .../src/types/interaction/markers/to_self.rs | 11 +- .../tx_exec/tx_exec_async_promises.rs | 6 +- .../base/src/types/managed/basic/big_float.rs | 38 ++--- .../managed/basic/big_float_operators.rs | 6 +- .../base/src/types/managed/basic/big_int.rs | 44 +++-- .../types/managed/basic/big_int_operators.rs | 25 +-- .../src/types/managed/basic/elliptic_curve.rs | 152 ++++++++++-------- .../src/types/managed/basic/managed_buffer.rs | 81 +++++++--- .../src/types/managed/basic/managed_map.rs | 19 ++- .../src/types/managed/managed_type_trait.rs | 4 +- .../multi_value/multi_value_encoded.rs | 2 +- .../multi_value/multi_value_managed_vec.rs | 2 +- .../src/types/managed/wrapped/big_uint.rs | 53 +++--- .../managed/wrapped/big_uint_operators.rs | 16 +- .../wrapped/egld_or_esdt_token_identifier.rs | 20 ++- .../types/managed/wrapped/managed_address.rs | 28 +++- .../managed/wrapped/managed_byte_array.rs | 13 +- .../managed_decimal_logarithm.rs | 7 +- .../managed_decimal/managed_decimal_signed.rs | 18 +-- .../types/managed/wrapped/managed_option.rs | 11 +- .../src/types/managed/wrapped/managed_ref.rs | 2 +- .../src/types/managed/wrapped/managed_vec.rs | 3 +- .../types/managed/wrapped/managed_vec_item.rs | 6 +- .../types/managed/wrapped/token_identifier.rs | 16 +- 40 files changed, 572 insertions(+), 387 deletions(-) diff --git a/contracts/feature-tests/basic-features/src/storage_direct_load.rs b/contracts/feature-tests/basic-features/src/storage_direct_load.rs index efdd51a20f..7d19f83eb5 100644 --- a/contracts/feature-tests/basic-features/src/storage_direct_load.rs +++ b/contracts/feature-tests/basic-features/src/storage_direct_load.rs @@ -1,7 +1,5 @@ multiversx_sc::imports!(); -use multiversx_sc::api::{use_raw_handle, HandleTypeInfo}; - use crate::types::*; /// Storage tests: direct load. @@ -78,16 +76,15 @@ pub trait StorageLoadFeatures { #[endpoint] fn load_from_address_raw(&self, address: ManagedAddress, key: ManagedBuffer) -> ManagedBuffer { // TODO: maybe wrap this kind of functionality in a StorageRawWrapper - use multiversx_sc::api::{ - StaticVarApi, StaticVarApiImpl, StorageReadApi, StorageReadApiImpl, - }; - let value_handle: <::Api as HandleTypeInfo>::ManagedBufferHandle = - use_raw_handle(Self::Api::static_var_api_impl().next_handle()); - Self::Api::storage_read_api_impl().storage_load_from_address( - address.get_handle(), - key.get_handle(), - value_handle.clone(), - ); - ManagedBuffer::from_handle(value_handle) + use multiversx_sc::api::{StorageReadApi, StorageReadApiImpl}; + unsafe { + let value = ManagedBuffer::new_uninit(); + Self::Api::storage_read_api_impl().storage_load_from_address( + address.get_handle(), + key.get_handle(), + value.get_handle(), + ); + value + } } } diff --git a/contracts/modules/src/esdt.rs b/contracts/modules/src/esdt.rs index ea977f53be..42314e9608 100644 --- a/contracts/modules/src/esdt.rs +++ b/contracts/modules/src/esdt.rs @@ -84,7 +84,9 @@ pub trait EsdtModule { fn nft_create(&self, amount: &BigUint, attributes: &T) -> u64 { let token_id = self.token_id().get(); let empty_buffer = ManagedBuffer::new(); - let empty_vec = ManagedVec::from_handle(empty_buffer.get_handle()); + + // sneakily reuses the same handle + let empty_vec = unsafe { ManagedRef::wrap_handle(empty_buffer.get_handle()) }; self.send().esdt_nft_create( &token_id, diff --git a/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs b/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs index c499c9f663..e769bb69c7 100644 --- a/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs @@ -11,8 +11,8 @@ use crate::{ storage::{self}, types::{ BackTransfers, BigUint, CodeMetadata, EgldOrEsdtTokenIdentifier, EsdtLocalRoleFlags, - EsdtTokenData, EsdtTokenType, ManagedAddress, ManagedBuffer, ManagedByteArray, ManagedType, - ManagedVec, TokenIdentifier, + EsdtTokenData, EsdtTokenType, ManagedAddress, ManagedBuffer, ManagedByteArray, + ManagedRefMut, ManagedType, ManagedVec, TokenIdentifier, }, }; @@ -49,9 +49,11 @@ where #[inline] pub fn get_caller(&self) -> ManagedAddress { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_caller_managed(handle.clone()); - ManagedAddress::from_handle(handle) + unsafe { + let result = ManagedAddress::new_uninit(); + A::blockchain_api_impl().load_caller_managed(result.get_handle()); + result + } } #[deprecated(since = "0.41.0", note = "Please use method `get_sc_address` instead.")] @@ -63,16 +65,20 @@ where #[inline] pub fn get_sc_address(&self) -> ManagedAddress { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_sc_address_managed(handle.clone()); - ManagedAddress::from_handle(handle) + unsafe { + let result = ManagedAddress::new_uninit(); + A::blockchain_api_impl().load_sc_address_managed(result.get_handle()); + result + } } #[inline] pub fn get_owner_address(&self) -> ManagedAddress { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_owner_address_managed(handle.clone()); - ManagedAddress::from_handle(handle) + unsafe { + let result = ManagedAddress::new_uninit(); + A::blockchain_api_impl().load_owner_address_managed(result.get_handle()); + result + } } pub fn check_caller_is_owner(&self) { @@ -123,16 +129,20 @@ where #[cfg(feature = "alloc")] #[inline] pub fn get_balance_legacy(&self, address: &crate::types::Address) -> BigUint { - let handle: A::BigIntHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_balance_legacy(handle.clone(), address); - BigUint::from_handle(handle) + unsafe { + let result = BigUint::new_uninit(); + A::blockchain_api_impl().load_balance_legacy(result.get_handle(), address); + result + } } #[inline] pub fn get_balance(&self, address: &ManagedAddress) -> BigUint { - let handle: A::BigIntHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_balance(handle.clone(), address.get_handle()); - BigUint::from_handle(handle) + unsafe { + let result = BigUint::new_uninit(); + A::blockchain_api_impl().load_balance(result.get_handle(), address.get_handle()); + result + } } #[inline] @@ -141,7 +151,10 @@ where A::blockchain_api_impl() .managed_get_code_metadata(address.get_handle(), mbuf_temp_1.clone()); let mut buffer = [0u8; 2]; - ManagedBuffer::::from_handle(mbuf_temp_1).load_to_byte_array(&mut buffer); + unsafe { + ManagedRefMut::<'static, A, ManagedBuffer>::wrap_handle(mbuf_temp_1) + .load_to_byte_array(&mut buffer); + } CodeMetadata::from(buffer) } @@ -173,9 +186,11 @@ where #[inline] pub fn get_state_root_hash(&self) -> ManagedByteArray { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_state_root_hash_managed(handle.clone()); - ManagedByteArray::from_handle(handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::blockchain_api_impl().load_state_root_hash_managed(result.get_handle()); + result + } } #[deprecated(since = "0.41.0", note = "Please use method `get_tx_hash` instead.")] @@ -187,9 +202,11 @@ where #[inline] pub fn get_tx_hash(&self) -> ManagedByteArray { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_tx_hash_managed(handle.clone()); - ManagedByteArray::from_handle(handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::blockchain_api_impl().load_tx_hash_managed(result.get_handle()); + result + } } #[inline] @@ -229,9 +246,11 @@ where #[inline] pub fn get_block_random_seed(&self) -> ManagedByteArray { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_block_random_seed_managed(handle.clone()); - ManagedByteArray::from_handle(handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::blockchain_api_impl().load_block_random_seed_managed(result.get_handle()); + result + } } #[inline] @@ -266,9 +285,11 @@ where #[inline] pub fn get_prev_block_random_seed(&self) -> ManagedByteArray { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_prev_block_random_seed_managed(handle.clone()); - ManagedByteArray::from_handle(handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::blockchain_api_impl().load_prev_block_random_seed_managed(result.get_handle()); + result + } } #[inline] @@ -288,14 +309,16 @@ where token_id: &TokenIdentifier, nonce: u64, ) -> BigUint { - let result_handle: A::BigIntHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_esdt_balance( - address.get_handle(), - token_id.get_handle(), - nonce, - result_handle.clone(), - ); - BigUint::from_handle(result_handle) + unsafe { + let result = BigUint::new_uninit(); + A::blockchain_api_impl().load_esdt_balance( + address.get_handle(), + token_id.get_handle(), + nonce, + result.get_handle(), + ); + result + } } pub fn get_esdt_token_data( @@ -346,16 +369,18 @@ where let _ = managed_api_impl.mb_load_slice(properties_handle, 0, &mut properties_bytes[..]); let frozen = esdt_is_frozen(&properties_bytes); - EsdtTokenData { - token_type, - amount: BigUint::from_raw_handle(value_handle.get_raw_handle()), - frozen, - hash: ManagedBuffer::from_raw_handle(hash_handle.get_raw_handle()), - name: ManagedBuffer::from_raw_handle(name_handle.get_raw_handle()), - attributes: ManagedBuffer::from_raw_handle(attributes_handle.get_raw_handle()), - creator: ManagedAddress::from_raw_handle(creator_handle.get_raw_handle()), - royalties: BigUint::from_raw_handle(royalties_handle.get_raw_handle()), - uris: ManagedVec::from_raw_handle(uris_handle.get_raw_handle()), + unsafe { + EsdtTokenData { + token_type, + amount: BigUint::from_raw_handle(value_handle.get_raw_handle()), + frozen, + hash: ManagedBuffer::from_raw_handle(hash_handle.get_raw_handle()), + name: ManagedBuffer::from_raw_handle(name_handle.get_raw_handle()), + attributes: ManagedBuffer::from_raw_handle(attributes_handle.get_raw_handle()), + creator: ManagedAddress::from_raw_handle(creator_handle.get_raw_handle()), + royalties: BigUint::from_raw_handle(royalties_handle.get_raw_handle()), + uris: ManagedVec::from_raw_handle(uris_handle.get_raw_handle()), + } } } @@ -375,9 +400,13 @@ where call_value_handle.get_raw_handle(), ); - BackTransfers { - total_egld_amount: BigUint::from_raw_handle(call_value_handle.get_raw_handle()), - esdt_payments: ManagedVec::from_raw_handle(esdt_transfer_value_handle.get_raw_handle()), + unsafe { + BackTransfers { + total_egld_amount: BigUint::from_raw_handle(call_value_handle.get_raw_handle()), + esdt_payments: ManagedVec::from_raw_handle( + esdt_transfer_value_handle.get_raw_handle(), + ), + } } } @@ -441,13 +470,11 @@ where // load value A::storage_read_api_impl() .storage_load_managed_buffer_raw(temp_handle_1, temp_handle_2.clone()); - let result_handle: A::BigIntHandle = use_raw_handle(A::static_var_api_impl().next_handle()); // convert value to BigUint - A::managed_type_impl().mb_to_big_int_unsigned(temp_handle_2, result_handle.clone()); - - //wrap - BigUint::from_handle(result_handle) + let result = unsafe { BigUint::new_uninit() }; + A::managed_type_impl().mb_to_big_int_unsigned(temp_handle_2, result.get_handle()); + result } } diff --git a/framework/base/src/contract_base/wrappers/crypto_wrapper.rs b/framework/base/src/contract_base/wrappers/crypto_wrapper.rs index 369cca1a63..3731d4a964 100644 --- a/framework/base/src/contract_base/wrappers/crypto_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/crypto_wrapper.rs @@ -1,10 +1,7 @@ use core::marker::PhantomData; use crate::{ - api::{ - use_raw_handle, CryptoApi, CryptoApiImpl, StaticVarApiImpl, KECCAK256_RESULT_LEN, - SHA256_RESULT_LEN, - }, + api::{CryptoApi, CryptoApiImpl, KECCAK256_RESULT_LEN, SHA256_RESULT_LEN}, types::{ManagedBuffer, ManagedByteArray, ManagedType, ManagedVec, MessageHashType}, }; @@ -30,30 +27,33 @@ where &self, data: B, ) -> ManagedByteArray { - let new_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::crypto_api_impl().sha256_managed(new_handle.clone(), data.borrow().get_handle()); - ManagedByteArray::from_handle(new_handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::crypto_api_impl().sha256_managed(result.get_handle(), data.borrow().get_handle()); + result + } } pub fn keccak256>>( &self, data: B, ) -> ManagedByteArray { - let new_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::crypto_api_impl().keccak256_managed(new_handle.clone(), data.borrow().get_handle()); - ManagedByteArray::from_handle(new_handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::crypto_api_impl().keccak256_managed(result.get_handle(), data.borrow().get_handle()); + result + } } pub fn ripemd160>>( &self, data: B, ) -> ManagedByteArray { - let new_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::crypto_api_impl().ripemd160_managed(new_handle.clone(), data.borrow().get_handle()); - ManagedByteArray::from_handle(new_handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::crypto_api_impl().ripemd160_managed(result.get_handle(), data.borrow().get_handle()); + result + } } pub fn verify_bls( @@ -122,14 +122,15 @@ where r: &ManagedBuffer, s: &ManagedBuffer, ) -> ManagedBuffer { - let new_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::crypto_api_impl().encode_secp256k1_der_signature_managed( - r.get_handle(), - s.get_handle(), - new_handle.clone(), - ); - ManagedBuffer::from_handle(new_handle) + unsafe { + let result = ManagedBuffer::new_uninit(); + A::crypto_api_impl().encode_secp256k1_der_signature_managed( + r.get_handle(), + s.get_handle(), + result.get_handle(), + ); + result + } } /// Calls the Vm to verify secp256r1 signature. diff --git a/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs b/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs index 5d290369df..07466ac234 100644 --- a/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs @@ -192,10 +192,12 @@ where new_address_handle, result_handle, ); - ( - ManagedAddress::from_raw_handle(new_address_handle), - ManagedVec::from_raw_handle(result_handle), - ) + unsafe { + ( + ManagedAddress::from_raw_handle(new_address_handle), + ManagedVec::from_raw_handle(result_handle), + ) + } } /// Deploys a new contract in the same shard by re-using the code of an already deployed source contract. @@ -222,10 +224,12 @@ where new_address_handle, result_handle, ); - ( - ManagedAddress::from_raw_handle(new_address_handle), - ManagedVec::from_raw_handle(result_handle), - ) + unsafe { + ( + ManagedAddress::from_raw_handle(new_address_handle), + ManagedVec::from_raw_handle(result_handle), + ) + } } pub fn upgrade_from_source_contract( @@ -291,7 +295,7 @@ where arg_buffer.get_handle().get_raw_handle(), result_handle, ); - ManagedVec::from_raw_handle(result_handle) + unsafe { ManagedVec::from_raw_handle(result_handle) } } pub fn execute_on_same_context_raw( @@ -311,7 +315,7 @@ where arg_buffer.get_handle().get_raw_handle(), result_handle, ); - ManagedVec::from_raw_handle(result_handle) + unsafe { ManagedVec::from_raw_handle(result_handle) } } /// Same shard, in-line execution of another contract. @@ -330,7 +334,7 @@ where arg_buffer.get_handle().get_raw_handle(), result_handle, ); - ManagedVec::from_raw_handle(result_handle) + unsafe { ManagedVec::from_raw_handle(result_handle) } } /// Allows synchronously calling a local function by name. Execution is resumed afterwards. @@ -357,8 +361,7 @@ where ); self.clean_return_data(); - - ManagedVec::from_raw_handle(result_handle) + unsafe { ManagedVec::from_raw_handle(result_handle) } } pub fn clean_return_data(&self) { diff --git a/framework/base/src/contract_base/wrappers/send_wrapper.rs b/framework/base/src/contract_base/wrappers/send_wrapper.rs index 3a11bde247..0c23b67cd4 100644 --- a/framework/base/src/contract_base/wrappers/send_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/send_wrapper.rs @@ -2,6 +2,7 @@ use core::marker::PhantomData; use crate::codec::Empty; +use crate::types::ManagedRef; use crate::{ api::{BlockchainApi, CallTypeApi, StorageReadApi}, codec, @@ -589,7 +590,9 @@ where ) -> u64 { let big_zero = BigUint::zero(); let empty_buffer = ManagedBuffer::new(); - let empty_vec = ManagedVec::from_handle(empty_buffer.get_handle()); + + // sneakily reuses the same handle + let empty_vec = unsafe { ManagedRef::wrap_handle(empty_buffer.get_handle()) }; self.esdt_nft_create( token, diff --git a/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs b/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs index 7417d6ca52..9fd49e115b 100644 --- a/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs @@ -59,7 +59,8 @@ where V: TopDecode, { let key: StorageKey = storage_key.into(); - let result_buffer = ManagedBuffer::::from_handle(use_raw_handle(MBUF_TEMPORARY_1)); + let result_buffer = + unsafe { ManagedBuffer::::from_handle(use_raw_handle(MBUF_TEMPORARY_1)) }; A::storage_read_api_impl().storage_load_from_address( address.get_handle(), key.get_handle(), diff --git a/framework/base/src/io/arg_de_input.rs b/framework/base/src/io/arg_de_input.rs index 98faef2899..7c84d9cbb9 100644 --- a/framework/base/src/io/arg_de_input.rs +++ b/framework/base/src/io/arg_de_input.rs @@ -1,10 +1,7 @@ use core::marker::PhantomData; use crate::{ - api::{ - use_raw_handle, EndpointArgumentApi, EndpointArgumentApiImpl, ManagedTypeApi, - StaticVarApiImpl, - }, + api::{EndpointArgumentApi, EndpointArgumentApiImpl, ManagedTypeApi}, codec::{ try_execute_then_cast, DecodeError, DecodeErrorHandler, TopDecodeInput, TryStaticCast, }, @@ -43,22 +40,34 @@ where } fn to_managed_buffer(&self) -> ManagedBuffer { - let mbuf_handle: AA::ManagedBufferHandle = - use_raw_handle(AA::static_var_api_impl().next_handle()); - AA::argument_api_impl().load_argument_managed_buffer(self.arg_index, mbuf_handle.clone()); - ManagedBuffer::from_handle(mbuf_handle) + unsafe { + let result = ManagedBuffer::new_uninit(); + AA::argument_api_impl() + .load_argument_managed_buffer(self.arg_index, result.get_handle()); + result + } } fn to_big_int(&self) -> BigInt { - let bi_handle: AA::BigIntHandle = use_raw_handle(AA::static_var_api_impl().next_handle()); - AA::argument_api_impl().load_argument_big_int_signed(self.arg_index, bi_handle.clone()); - BigInt::from_handle(bi_handle) + unsafe { + let result = BigInt::new_uninit(); + AA::argument_api_impl() + .load_argument_big_int_signed(self.arg_index, result.get_handle()); + result + } } fn to_big_uint(&self) -> BigUint { - let bi_handle: AA::BigIntHandle = use_raw_handle(AA::static_var_api_impl().next_handle()); - AA::argument_api_impl().load_argument_big_int_unsigned(self.arg_index, bi_handle.clone()); - BigUint::from_handle(bi_handle) + unsafe { + let result = BigUint::new_uninit(); + AA::argument_api_impl() + .load_argument_big_int_unsigned(self.arg_index, result.get_handle()); + result + } + + // let bi_handle: AA::BigIntHandle = use_raw_handle(AA::static_var_api_impl().next_handle()); + // AA::argument_api_impl().load_argument_big_int_unsigned(self.arg_index, bi_handle.clone()); + // BigUint::from_handle(bi_handle) } } diff --git a/framework/base/src/io/arg_nested_tuple.rs b/framework/base/src/io/arg_nested_tuple.rs index fca34c9886..1a0eaace7a 100644 --- a/framework/base/src/io/arg_nested_tuple.rs +++ b/framework/base/src/io/arg_nested_tuple.rs @@ -198,13 +198,15 @@ fn callback_closure_args_loader() -> ManagedResultArgLoader where AA: VMApi, { - AA::argument_api_impl() - .load_callback_closure_buffer(use_raw_handle(const_handles::MBUF_TEMPORARY_1)); - let cb_closure_args_serialized = - ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); - let mut cb_closure_args_buffer = - ManagedArgBuffer::::from_raw_handle(const_handles::CALLBACK_CLOSURE_ARGS_BUFFER); - cb_closure_args_buffer.deserialize_overwrite(cb_closure_args_serialized); - - ManagedResultArgLoader::new(cb_closure_args_buffer.into_vec_of_buffers()) + unsafe { + AA::argument_api_impl() + .load_callback_closure_buffer(use_raw_handle(const_handles::MBUF_TEMPORARY_1)); + let cb_closure_args_serialized = + ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); + let mut cb_closure_args_buffer = + ManagedArgBuffer::::from_raw_handle(const_handles::CALLBACK_CLOSURE_ARGS_BUFFER); + cb_closure_args_buffer.deserialize_overwrite(cb_closure_args_serialized); + + ManagedResultArgLoader::new(cb_closure_args_buffer.into_vec_of_buffers()) + } } diff --git a/framework/base/src/storage/storage_get.rs b/framework/base/src/storage/storage_get.rs index 85107896dd..b33b5e1dcb 100644 --- a/framework/base/src/storage/storage_get.rs +++ b/framework/base/src/storage/storage_get.rs @@ -3,7 +3,7 @@ use core::{convert::Infallible, marker::PhantomData}; use crate::{ api::{ const_handles, use_raw_handle, ErrorApi, ErrorApiImpl, HandleConstraints, - ManagedBufferApiImpl, ManagedTypeApi, StaticVarApiImpl, StorageReadApi, StorageReadApiImpl, + ManagedBufferApiImpl, ManagedTypeApi, StorageReadApi, StorageReadApiImpl, }, codec::*, err_msg, @@ -33,11 +33,12 @@ where } fn to_managed_buffer(&self) -> ManagedBuffer { - let mbuf_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::storage_read_api_impl() - .storage_load_managed_buffer_raw(self.key.buffer.get_handle(), mbuf_handle.clone()); - ManagedBuffer::from_handle(mbuf_handle) + unsafe { + let result = ManagedBuffer::new_uninit(); + A::storage_read_api_impl() + .storage_load_managed_buffer_raw(self.key.buffer.get_handle(), result.get_handle()); + result + } } fn to_big_uint(&self) -> BigUint { diff --git a/framework/base/src/storage/storage_get_from_address.rs b/framework/base/src/storage/storage_get_from_address.rs index 2b40987bd3..13a467d2f0 100644 --- a/framework/base/src/storage/storage_get_from_address.rs +++ b/framework/base/src/storage/storage_get_from_address.rs @@ -1,7 +1,7 @@ use crate::{ api::{ const_handles, use_raw_handle, ErrorApi, HandleConstraints, ManagedBufferApiImpl, - ManagedTypeApi, StaticVarApiImpl, StorageReadApi, StorageReadApiImpl, + ManagedTypeApi, StorageReadApi, StorageReadApiImpl, }, codec::*, types::{ @@ -35,15 +35,15 @@ where } fn to_managed_buffer(&self) -> ManagedBuffer { - let mbuf_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::storage_read_api_impl().storage_load_from_address( - self.addr.get_handle(), - self.key.buffer.get_handle(), - mbuf_handle.clone(), - ); - - ManagedBuffer::from_handle(mbuf_handle) + unsafe { + let result = ManagedBuffer::new_uninit(); + A::storage_read_api_impl().storage_load_from_address( + self.addr.get_handle(), + self.key.buffer.get_handle(), + result.get_handle(), + ); + result + } } fn to_big_uint(&self) -> BigUint { diff --git a/framework/base/src/storage/storage_key.rs b/framework/base/src/storage/storage_key.rs index f692dd5266..b3a35643e1 100644 --- a/framework/base/src/storage/storage_key.rs +++ b/framework/base/src/storage/storage_key.rs @@ -22,7 +22,7 @@ where type OwnHandle = A::ManagedBufferHandle; #[inline] - fn from_handle(handle: A::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: A::ManagedBufferHandle) -> Self { StorageKey { buffer: ManagedBuffer::from_handle(handle), } diff --git a/framework/base/src/types/interaction/contract_call_legacy/async_call_promises.rs b/framework/base/src/types/interaction/contract_call_legacy/async_call_promises.rs index ee3726c0eb..f2d091e2b3 100644 --- a/framework/base/src/types/interaction/contract_call_legacy/async_call_promises.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/async_call_promises.rs @@ -1,5 +1,7 @@ +use core::ops::DerefMut; + use crate::{ - api::CallTypeApi, + api::{const_handles, CallTypeApi}, contract_base::SendRawWrapper, types::{BigUint, CallbackClosure, FunctionCall, ManagedAddress, ManagedBuffer}, }; @@ -41,16 +43,14 @@ where } pub fn register_promise(self) { - use crate::{api::const_handles, types::ManagedType}; - let mut cb_closure_args_serialized = - ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); + unsafe { ManagedBuffer::temp_const_ref_mut(const_handles::MBUF_TEMPORARY_1) }; let callback_name; if let Some(callback_call) = self.callback_call { callback_name = callback_call.callback_name; callback_call .closure_args - .serialize_overwrite(&mut cb_closure_args_serialized); + .serialize_overwrite(cb_closure_args_serialized.deref_mut()); } else { callback_name = ""; cb_closure_args_serialized.overwrite(&[]); diff --git a/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs index 427218f1c8..f0f1722f24 100644 --- a/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs @@ -36,10 +36,12 @@ where call_value_handle.get_raw_handle(), ); - ( - BigUint::from_raw_handle(call_value_handle.get_raw_handle()), - ManagedVec::from_raw_handle(esdt_transfer_value_handle.get_raw_handle()), - ) + unsafe { + ( + BigUint::from_raw_handle(call_value_handle.get_raw_handle()), + ManagedVec::from_raw_handle(esdt_transfer_value_handle.get_raw_handle()), + ) + } } pub fn to_call_data_string(&self) -> ManagedBuffer { diff --git a/framework/base/src/types/interaction/managed_arg_buffer.rs b/framework/base/src/types/interaction/managed_arg_buffer.rs index bd98c40931..009ad74e3a 100644 --- a/framework/base/src/types/interaction/managed_arg_buffer.rs +++ b/framework/base/src/types/interaction/managed_arg_buffer.rs @@ -33,7 +33,7 @@ where type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { ManagedArgBuffer { data: ManagedVec::from_handle(handle), } diff --git a/framework/base/src/types/interaction/markers/to_caller.rs b/framework/base/src/types/interaction/markers/to_caller.rs index f24191ce9f..9066a16239 100644 --- a/framework/base/src/types/interaction/markers/to_caller.rs +++ b/framework/base/src/types/interaction/markers/to_caller.rs @@ -1,5 +1,5 @@ use crate::{ - api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi}, + api::{const_handles, BlockchainApi, BlockchainApiImpl, CallTypeApi}, contract_base::BlockchainWrapper, types::{ AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv, TxTo, TxToSpecified, @@ -25,9 +25,11 @@ where where F: FnOnce(&ManagedAddress) -> 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)) + unsafe { + let temp = ManagedAddress::temp_const_ref(const_handles::ADDRESS_CALLER); + Api::blockchain_api_impl().load_caller_managed(temp.get_handle()); + f(&temp) + } } } diff --git a/framework/base/src/types/interaction/markers/to_self.rs b/framework/base/src/types/interaction/markers/to_self.rs index f339a448e2..8a78e13d6d 100644 --- a/framework/base/src/types/interaction/markers/to_self.rs +++ b/framework/base/src/types/interaction/markers/to_self.rs @@ -1,5 +1,5 @@ use crate::{ - api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi}, + api::{const_handles, BlockchainApi, BlockchainApiImpl, CallTypeApi}, contract_base::BlockchainWrapper, types::{ AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv, TxTo, TxToSpecified, @@ -26,10 +26,11 @@ where where F: FnOnce(&ManagedAddress) -> 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)) + unsafe { + let temp = ManagedAddress::temp_const_ref(const_handles::ADDRESS_CALLER); + Api::blockchain_api_impl().load_sc_address_managed(temp.get_handle()); + f(&temp) + } } } diff --git a/framework/base/src/types/interaction/tx_exec/tx_exec_async_promises.rs b/framework/base/src/types/interaction/tx_exec/tx_exec_async_promises.rs index 38e38fcbcd..333bbf9379 100644 --- a/framework/base/src/types/interaction/tx_exec/tx_exec_async_promises.rs +++ b/framework/base/src/types/interaction/tx_exec/tx_exec_async_promises.rs @@ -3,8 +3,8 @@ use crate::{ contract_base::{ErrorHelper, SendRawWrapper}, types::{ interaction::callback_closure::CallbackClosureWithGas, CallbackClosure, ExplicitGas, - FunctionCall, ManagedBuffer, ManagedType, OriginalResultMarker, Tx, TxGas, TxGasValue, - TxPayment, TxResultHandler, TxScEnv, TxToSpecified, + FunctionCall, ManagedBuffer, OriginalResultMarker, Tx, TxGas, TxGasValue, TxPayment, + TxResultHandler, TxScEnv, TxToSpecified, }, }; @@ -160,7 +160,7 @@ where pub fn register_promise(self) { let callback_name = self.result_handler.callback_name(); let mut cb_closure_args_serialized = - ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); + unsafe { ManagedBuffer::temp_const_ref_mut(const_handles::MBUF_TEMPORARY_1) }; self.result_handler .overwrite_with_serialized_args(&mut cb_closure_args_serialized); let extra_gas_for_callback = self.result_handler.gas_for_callback(); diff --git a/framework/base/src/types/managed/basic/big_float.rs b/framework/base/src/types/managed/basic/big_float.rs index 802d582e94..8361cb4b79 100644 --- a/framework/base/src/types/managed/basic/big_float.rs +++ b/framework/base/src/types/managed/basic/big_float.rs @@ -27,7 +27,7 @@ pub struct BigFloat { impl ManagedType for BigFloat { type OwnHandle = M::BigFloatHandle; - fn from_handle(handle: M::BigFloatHandle) -> Self { + unsafe fn from_handle(handle: M::BigFloatHandle) -> Self { BigFloat { handle } } @@ -88,7 +88,7 @@ macro_rules! big_float_conv_num { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_set_i64(new_bf_handle.clone(), value as i64); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } } }; @@ -105,28 +105,28 @@ impl BigFloat { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_neg(new_bf_handle.clone(), self.handle.clone()); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } pub fn abs(&self) -> Self { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_abs(new_bf_handle.clone(), self.handle.clone()); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } pub fn from_big_uint(big_uint: &BigUint) -> Self { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_set_bi(new_bf_handle.clone(), big_uint.value.handle.clone()); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } pub fn from_big_int(big_int: &BigInt) -> Self { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_set_bi(new_bf_handle.clone(), big_int.handle.clone()); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } #[inline] @@ -138,42 +138,42 @@ impl BigFloat { let api = M::managed_type_impl(); let new_bf_handle = api.bf_from_parts(integral_part_value, fractional_part_value, exponent_value); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } #[inline] pub fn from_frac(numerator_value: i64, denominator_value: i64) -> Self { let api = M::managed_type_impl(); let new_bf_handle = api.bf_from_frac(numerator_value, denominator_value); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } #[inline] pub fn from_sci(significand_value: i64, exponent_value: i32) -> Self { let api = M::managed_type_impl(); let new_bf_handle = api.bf_from_sci(significand_value, exponent_value as i64); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } pub fn trunc(&self) -> BigInt { let result: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); let api = M::managed_type_impl(); api.bf_trunc(result.clone(), self.handle.clone()); - BigInt::from_handle(result) + unsafe { BigInt::from_handle(result) } } pub fn floor(&self) -> BigInt { let result: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); let api = M::managed_type_impl(); api.bf_floor(result.clone(), self.handle.clone()); - BigInt::from_handle(result) + unsafe { BigInt::from_handle(result) } } pub fn ceil(&self) -> BigInt { let result: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); let api = M::managed_type_impl(); api.bf_ceil(result.clone(), self.handle.clone()); - BigInt::from_handle(result) + unsafe { BigInt::from_handle(result) } } pub fn to_fixed_point(&self, denominator: &BigFloat) -> BigInt { @@ -254,7 +254,7 @@ impl BigFloat { #[inline] pub fn zero() -> Self { - BigFloat::from_handle(M::managed_type_impl().bf_new_zero()) + unsafe { BigFloat::from_handle(M::managed_type_impl().bf_new_zero()) } } pub fn from_buffer(managed_buffer: &ManagedBuffer) -> Self { @@ -262,14 +262,14 @@ impl BigFloat { use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl() .mb_to_big_float(managed_buffer.handle.clone(), new_bf_handle.clone()); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } pub fn to_buffer(&self) -> ManagedBuffer { let new_man_buf_handle: M::ManagedBufferHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().mb_from_big_float(self.handle.clone(), new_man_buf_handle.clone()); - ManagedBuffer::from_handle(new_man_buf_handle) + unsafe { ManagedBuffer::from_handle(new_man_buf_handle) } } } @@ -278,14 +278,14 @@ impl BigFloat { let api = M::managed_type_impl(); let new_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); api.bf_sqrt(new_handle.clone(), self.handle.clone()); - BigFloat::from_handle(new_handle) + unsafe { BigFloat::from_handle(new_handle) } } pub fn pow(&self, exp: i32) -> Self { let api = M::managed_type_impl(); let new_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); api.bf_pow(new_handle.clone(), self.handle.clone(), exp); - BigFloat::from_handle(new_handle) + unsafe { BigFloat::from_handle(new_handle) } } /// Returns the sign of the `BigFloat` as a `Sign`. @@ -301,7 +301,7 @@ impl BigFloat { pub fn magnitude(&self) -> BigFloat { let result: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_abs(result.clone(), self.handle.clone()); - BigFloat::from_handle(result) + unsafe { BigFloat::from_handle(result) } } /// Convert this `BigFloat` into its `Sign` and its magnitude, @@ -343,7 +343,7 @@ impl Clone for BigFloat { fn clone(&self) -> Self { let new_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_clone(new_handle.clone(), self.handle.clone()); - BigFloat::from_handle(new_handle) + unsafe { BigFloat::from_handle(new_handle) } } } diff --git a/framework/base/src/types/managed/basic/big_float_operators.rs b/framework/base/src/types/managed/basic/big_float_operators.rs index 7874c1ab86..7333a69ebe 100644 --- a/framework/base/src/types/managed/basic/big_float_operators.rs +++ b/framework/base/src/types/managed/basic/big_float_operators.rs @@ -16,7 +16,7 @@ macro_rules! binary_operator { self.handle.clone(), other.handle.clone(), ); - BigFloat::from_handle(self.handle.clone()) + unsafe { BigFloat::from_handle(self.handle.clone()) } } } @@ -31,7 +31,7 @@ macro_rules! binary_operator { self.handle.clone(), other.handle.clone(), ); - BigFloat::from_handle(result_handle) + unsafe { BigFloat::from_handle(result_handle) } } } }; @@ -82,6 +82,6 @@ impl Neg for BigFloat { let result_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_neg(result_handle.clone(), self.handle); - BigFloat::from_handle(result_handle) + unsafe { BigFloat::from_handle(result_handle) } } } diff --git a/framework/base/src/types/managed/basic/big_int.rs b/framework/base/src/types/managed/basic/big_int.rs index cb52117c32..9727d81dd5 100644 --- a/framework/base/src/types/managed/basic/big_int.rs +++ b/framework/base/src/types/managed/basic/big_int.rs @@ -11,7 +11,9 @@ use crate::{ NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, TryStaticCast, }, formatter::{hex_util::encode_bytes_as_hex, FormatByteReceiver, SCDisplay}, - types::{heap::BoxedBytes, BigUint, ManagedBuffer, ManagedOption, ManagedType, Sign}, + types::{ + heap::BoxedBytes, BigUint, ManagedBuffer, ManagedOption, ManagedRef, ManagedType, Sign, + }, }; use super::cast_to_i64::cast_to_i64; @@ -25,7 +27,7 @@ pub struct BigInt { impl ManagedType for BigInt { type OwnHandle = M::BigIntHandle; - fn from_handle(handle: M::BigIntHandle) -> Self { + unsafe fn from_handle(handle: M::BigIntHandle) -> Self { BigInt { handle, _phantom: PhantomData, @@ -43,7 +45,6 @@ impl ManagedType for BigInt { fn transmute_from_handle_ref_mut(handle_ref: &mut M::BigIntHandle) -> &mut Self { unsafe { core::mem::transmute(handle_ref) } } - } impl Default for BigInt { @@ -68,6 +69,16 @@ impl From> for BigInt { } impl BigInt { + /// Creates a new object, without initializing it. + /// + /// ## Safety + /// + /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read. + pub unsafe fn new_uninit() -> Self { + let new_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); + BigInt::from_handle(new_handle) + } + pub(crate) fn set_value(handle: M::BigIntHandle, value: T) where T: TryInto, @@ -88,7 +99,7 @@ impl BigInt { impl From> for BigInt { #[inline] fn from(item: BigUint) -> Self { - BigInt::from_handle(item.get_handle()) + item.into_big_int() } } @@ -100,7 +111,7 @@ macro_rules! big_int_conv_num { let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); Self::set_value(handle.clone(), value); - BigInt::from_handle(handle) + unsafe { BigInt::from_handle(handle) } } } @@ -157,9 +168,8 @@ impl BigInt { #[inline] pub fn zero() -> Self { let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - // TODO: seting 0 will no longer be needed once we fix VM handle error M::managed_type_impl().bi_set_int64(handle.clone(), 0); - BigInt::from_handle(handle) + unsafe { BigInt::from_handle(handle) } } #[inline] @@ -178,7 +188,7 @@ impl BigInt { M::managed_type_impl().mb_overwrite(mb_handle.clone(), bytes); let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().mb_to_big_int_signed(mb_handle, handle.clone()); - BigInt::from_handle(handle) + unsafe { BigInt::from_handle(handle) } } #[inline] @@ -192,7 +202,7 @@ impl BigInt { pub fn from_signed_bytes_be_buffer(managed_buffer: &ManagedBuffer) -> Self { let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().mb_to_big_int_signed(managed_buffer.handle.clone(), handle.clone()); - BigInt::from_handle(handle) + unsafe { BigInt::from_handle(handle) } } #[inline] @@ -200,7 +210,7 @@ impl BigInt { let mb_handle: M::ManagedBufferHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().mb_from_big_int_signed(self.handle.clone(), mb_handle.clone()); - ManagedBuffer::from_handle(mb_handle) + unsafe { ManagedBuffer::from_handle(mb_handle) } } } @@ -214,7 +224,7 @@ impl Clone for BigInt { clone_handle.clone(), self.handle.clone(), ); - BigInt::from_handle(clone_handle) + unsafe { BigInt::from_handle(clone_handle) } } } @@ -224,7 +234,7 @@ impl BigInt { if sign.is_minus() { api.bi_neg(unsigned.value.handle.clone(), unsigned.value.handle.clone()); } - BigInt::from_handle(unsigned.value.handle) + unsafe { BigInt::from_handle(unsigned.value.handle) } } /// Returns the sign of the `BigInt` as a `Sign`. @@ -242,7 +252,7 @@ impl BigInt { let api = M::managed_type_impl(); let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); api.bi_abs(result_handle.clone(), self.handle.clone()); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } /// Convert this `BigInt` into its `Sign` and `BigUint` magnitude, @@ -335,7 +345,7 @@ impl BigInt { let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); let exp_handle = BigUint::::make_temp(const_handles::BIG_INT_TEMPORARY_1, exp); M::managed_type_impl().bi_pow(result_handle.clone(), self.handle.clone(), exp_handle); - BigInt::from_handle(result_handle) + unsafe { BigInt::from_handle(result_handle) } } } @@ -343,9 +353,9 @@ impl SCDisplay for BigInt { fn fmt(&self, f: &mut F) { let str_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); M::managed_type_impl().bi_to_string(self.handle.clone(), str_handle.clone()); - f.append_managed_buffer(&ManagedBuffer::from_handle( - str_handle.cast_or_signal_error::(), - )); + let cast_handle = str_handle.cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); } } diff --git a/framework/base/src/types/managed/basic/big_int_operators.rs b/framework/base/src/types/managed/basic/big_int_operators.rs index fed47d5a26..0cf00c66e6 100644 --- a/framework/base/src/types/managed/basic/big_int_operators.rs +++ b/framework/base/src/types/managed/basic/big_int_operators.rs @@ -19,7 +19,7 @@ macro_rules! binary_operator { self.handle.clone(), other.handle.clone(), ); - BigInt::from_handle(self.handle.clone()) + self } } @@ -44,14 +44,15 @@ macro_rules! binary_operator { fn $method(self, other: &BigInt) -> BigInt { let api = M::managed_type_impl(); - let result_handle: M::BigIntHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - api.$api_func( - result_handle.clone(), - self.handle.clone(), - other.handle.clone(), - ); - BigInt::from_handle(result_handle) + unsafe { + let result = BigInt::new_uninit(); + api.$api_func( + result.get_handle(), + self.handle.clone(), + other.handle.clone(), + ); + result + } } } @@ -59,7 +60,7 @@ macro_rules! binary_operator { type Output = BigInt; fn $method(self, other: &BigUint) -> BigInt { - self.$method(&BigInt::from_handle(other.get_handle())) + self.$method(other.as_big_int()) } } @@ -67,7 +68,7 @@ macro_rules! binary_operator { type Output = BigInt; fn $method(self, other: &BigInt) -> BigInt { - (&BigInt::from_handle(self.get_handle())).$method(other) + self.as_big_int().$method(other) } } }; @@ -120,6 +121,6 @@ impl Neg for BigInt { let api = M::managed_type_impl(); let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); api.bi_neg(result_handle.clone(), self.handle); - BigInt::from_handle(result_handle) + unsafe { BigInt::from_handle(result_handle) } } } diff --git a/framework/base/src/types/managed/basic/elliptic_curve.rs b/framework/base/src/types/managed/basic/elliptic_curve.rs index 8c110f6459..2cc7097a18 100644 --- a/framework/base/src/types/managed/basic/elliptic_curve.rs +++ b/framework/base/src/types/managed/basic/elliptic_curve.rs @@ -35,7 +35,7 @@ pub struct EllipticCurve { impl ManagedType for EllipticCurve { type OwnHandle = M::EllipticCurveHandle; - fn from_handle(handle: M::EllipticCurveHandle) -> Self { + unsafe fn from_handle(handle: M::EllipticCurveHandle) -> Self { EllipticCurve { handle } } @@ -55,12 +55,12 @@ impl ManagedType for EllipticCurve { impl EllipticCurve { pub fn from_name(name: &ManagedBuffer) -> Self { let handle = M::managed_type_impl().ec_create_from_name_mb(name.get_handle()); - EllipticCurve::from_handle(handle) + unsafe { EllipticCurve::from_handle(handle) } } pub fn from_name_str(name: &str) -> Self { let handle = M::managed_type_impl().ec_create_from_name_bytes(name.as_bytes()); - EllipticCurve::from_handle(handle) + unsafe { EllipticCurve::from_handle(handle) } } pub fn from_bitsize(bitsize: u32) -> Option { @@ -88,14 +88,16 @@ impl EllipticCurve { x_base_point_handle.clone(), y_base_point_handle.clone(), ); - ( - BigUint::from_handle(field_order_handle), - BigUint::from_handle(base_point_order_handle), - BigUint::from_handle(eq_constant_handle), - BigUint::from_handle(x_base_point_handle), - BigUint::from_handle(y_base_point_handle), - api.ec_curve_length(self.handle.clone()), - ) + unsafe { + ( + BigUint::from_handle(field_order_handle), + BigUint::from_handle(base_point_order_handle), + BigUint::from_handle(eq_constant_handle), + BigUint::from_handle(x_base_point_handle), + BigUint::from_handle(y_base_point_handle), + api.ec_curve_length(self.handle.clone()), + ) + } } pub fn get_curve_length(&self) -> u32 { @@ -127,10 +129,12 @@ impl EllipticCurve { x_second_point.value.handle, y_second_point.value.handle, ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } pub fn double(&self, x_point: BigUint, y_point: BigUint) -> (BigUint, BigUint) { @@ -144,10 +148,12 @@ impl EllipticCurve { x_point.value.handle, y_point.value.handle, ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } pub fn is_on_curve(&self, x_point: BigUint, y_point: BigUint) -> bool { @@ -177,10 +183,12 @@ impl EllipticCurve { y_point.value.handle, data, ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } pub fn scalar_mult( @@ -200,10 +208,12 @@ impl EllipticCurve { y_point.value.handle, data.get_handle(), ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } #[deprecated( @@ -220,10 +230,12 @@ impl EllipticCurve { self.handle.clone(), data, ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } pub fn scalar_base_mult(&self, data: &ManagedBuffer) -> (BigUint, BigUint) { @@ -236,10 +248,12 @@ impl EllipticCurve { self.handle.clone(), data.get_handle(), ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } #[deprecated(since = "0.41.0", note = "Please use method `marshal` instead.")] @@ -266,7 +280,7 @@ impl EllipticCurve { y_pair.value.handle, result_handle.clone(), ); - ManagedBuffer::from_handle(result_handle) + unsafe { ManagedBuffer::from_handle(result_handle) } } #[deprecated( @@ -296,7 +310,7 @@ impl EllipticCurve { y_pair.value.handle, result_handle.clone(), ); - ManagedBuffer::from_handle(result_handle) + unsafe { ManagedBuffer::from_handle(result_handle) } } #[deprecated(since = "0.41.0", note = "Please use method `unmarshal` instead.")] @@ -310,10 +324,12 @@ impl EllipticCurve { self.handle.clone(), data, ); - ( - BigUint::from_handle(x_pair_handle), - BigUint::from_handle(y_pair_handle), - ) + unsafe { + ( + BigUint::from_handle(x_pair_handle), + BigUint::from_handle(y_pair_handle), + ) + } } pub fn unmarshal(&self, data: &ManagedBuffer) -> (BigUint, BigUint) { @@ -326,10 +342,12 @@ impl EllipticCurve { self.handle.clone(), data.get_handle(), ); - ( - BigUint::from_handle(x_pair_handle), - BigUint::from_handle(y_pair_handle), - ) + unsafe { + ( + BigUint::from_handle(x_pair_handle), + BigUint::from_handle(y_pair_handle), + ) + } } #[deprecated( @@ -346,10 +364,12 @@ impl EllipticCurve { self.handle.clone(), data, ); - ( - BigUint::from_handle(x_pair_handle), - BigUint::from_handle(y_pair_handle), - ) + unsafe { + ( + BigUint::from_handle(x_pair_handle), + BigUint::from_handle(y_pair_handle), + ) + } } pub fn unmarshal_compressed(&self, data: &ManagedBuffer) -> (BigUint, BigUint) { @@ -362,10 +382,12 @@ impl EllipticCurve { self.handle.clone(), data.get_handle(), ); - ( - BigUint::from_handle(x_pair_handle), - BigUint::from_handle(y_pair_handle), - ) + unsafe { + ( + BigUint::from_handle(x_pair_handle), + BigUint::from_handle(y_pair_handle), + ) + } } #[deprecated(since = "0.41.0", note = "Please use method `generate_key` instead.")] @@ -379,11 +401,13 @@ impl EllipticCurve { y_pub_key_handle.clone(), self.handle.clone(), ); - ( - BigUint::from_handle(x_pub_key_handle), - BigUint::from_handle(y_pub_key_handle), - private_key, - ) + unsafe { + ( + BigUint::from_handle(x_pub_key_handle), + BigUint::from_handle(y_pub_key_handle), + private_key, + ) + } } pub fn generate_key(&self) -> (BigUint, BigUint, ManagedBuffer) { @@ -398,11 +422,13 @@ impl EllipticCurve { self.handle.clone(), private_key_handle.clone(), ); - ( - BigUint::from_handle(x_pub_key_handle), - BigUint::from_handle(y_pub_key_handle), - ManagedBuffer::from_handle(private_key_handle), - ) + unsafe { + ( + BigUint::from_handle(x_pub_key_handle), + BigUint::from_handle(y_pub_key_handle), + ManagedBuffer::from_handle(private_key_handle), + ) + } } } diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index 34ba82da14..d1e0b52f9e 100644 --- a/framework/base/src/types/managed/basic/managed_buffer.rs +++ b/framework/base/src/types/managed/basic/managed_buffer.rs @@ -2,7 +2,7 @@ use crate::{ abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{ use_raw_handle, ErrorApiImpl, HandleConstraints, InvalidSliceError, ManagedBufferApiImpl, - ManagedTypeApi, StaticVarApiImpl, + ManagedTypeApi, RawHandle, StaticVarApiImpl, }, codec::{ DecodeErrorHandler, Empty, EncodeErrorHandler, NestedDecode, NestedDecodeInput, @@ -14,7 +14,8 @@ use crate::{ SCLowerHex, }, types::{ - heap::BoxedBytes, ManagedBufferCachedBuilder, ManagedType, StaticBufferRef, + heap::BoxedBytes, ManagedBufferCachedBuilder, ManagedRef, ManagedRefMut, ManagedType, + StaticBufferRef, }, }; @@ -28,7 +29,7 @@ impl ManagedType for ManagedBuffer { type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { ManagedBuffer { handle } } @@ -48,29 +49,61 @@ impl ManagedType for ManagedBuffer { impl ManagedBuffer { #[inline] pub fn new() -> Self { - let new_handle: M::ManagedBufferHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - // TODO: remove after VM no longer crashes with "unknown handle": - M::managed_type_impl().mb_overwrite(new_handle.clone(), &[]); - ManagedBuffer::from_handle(new_handle) + Self::new_from_bytes(&[]) } #[inline] pub fn new_from_bytes(bytes: &[u8]) -> Self { - let new_handle: M::ManagedBufferHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mb_overwrite(new_handle.clone(), bytes); - ManagedBuffer::from_handle(new_handle) + unsafe { + let result = Self::new_uninit(); + M::managed_type_impl().mb_overwrite(result.get_handle(), bytes); + result + } } #[inline] pub fn new_random(nr_bytes: usize) -> Self { + unsafe { + let result = Self::new_uninit(); + M::managed_type_impl().mb_set_random(result.get_handle(), nr_bytes); + result + } + } + + /// Creates a new object, without initializing it. + /// + /// ## Safety + /// + /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read. + pub unsafe fn new_uninit() -> Self { let new_handle: M::ManagedBufferHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mb_set_random(new_handle.clone(), nr_bytes); ManagedBuffer::from_handle(new_handle) } + /// Creates a shared managed reference to a given raw handle. + /// + /// ## Safety + /// + /// The reference points to a shared value. Make sure the handle is not leaked. + + pub unsafe fn temp_const_ref( + raw_handle: RawHandle, + ) -> ManagedRef<'static, M, ManagedBuffer> { + ManagedRef::wrap_handle(use_raw_handle(raw_handle)) + } + + /// Creates a shared managed reference to a given raw handle. + /// + /// ## Safety + /// + /// The reference points to a shared value. Make sure the handle is not leaked. + pub unsafe fn temp_const_ref_mut( + raw_handle: RawHandle, + ) -> ManagedRefMut<'static, M, ManagedBuffer> { + ManagedRefMut::wrap_handle(use_raw_handle(raw_handle)) + } + fn load_static_cache(&self) -> StaticBufferRef where M: ManagedTypeApi, @@ -239,7 +272,7 @@ impl ManagedBuffer { result_handle.clone(), ); if err_result.is_ok() { - Some(ManagedBuffer::from_handle(result_handle)) + Some(unsafe { ManagedBuffer::from_handle(result_handle) }) } else { None } @@ -352,7 +385,7 @@ impl Clone for ManagedBuffer { let api = M::managed_type_impl(); let clone_handle = api.mb_new_empty(); api.mb_append(clone_handle.clone(), self.handle.clone()); - ManagedBuffer::from_handle(clone_handle) + unsafe { ManagedBuffer::from_handle(clone_handle) } } } @@ -482,9 +515,9 @@ impl TypeAbi for ManagedBuffer { impl SCDisplay for ManagedBuffer { fn fmt(&self, f: &mut F) { - f.append_managed_buffer(&ManagedBuffer::from_handle( - self.get_handle().cast_or_signal_error::(), - )); + let cast_handle = self.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); } } @@ -493,18 +526,18 @@ impl SCLowerHex for ManagedBuffer { let hex_handle: M::ManagedBufferHandle = use_raw_handle(crate::api::const_handles::MBUF_TEMPORARY_1); M::managed_type_impl().mb_to_hex(self.handle.clone(), hex_handle.clone()); - f.append_managed_buffer(&ManagedBuffer::from_handle( - hex_handle.cast_or_signal_error::(), - )); + let cast_handle = hex_handle.cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); } } impl SCBinary for ManagedBuffer { fn fmt(&self, f: &mut F) { // TODO: in Rust thr `0b` prefix appears only when writing "{:#x}", not "{:x}" - f.append_managed_buffer_binary(&ManagedBuffer::from_handle( - self.get_handle().cast_or_signal_error::(), - )); + let cast_handle = self.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer_binary(&wrap_cast); } } diff --git a/framework/base/src/types/managed/basic/managed_map.rs b/framework/base/src/types/managed/basic/managed_map.rs index ed39011f8d..0d7cc2f1b4 100644 --- a/framework/base/src/types/managed/basic/managed_map.rs +++ b/framework/base/src/types/managed/basic/managed_map.rs @@ -15,7 +15,7 @@ impl ManagedType for ManagedMap { type OwnHandle = M::ManagedMapHandle; #[inline] - fn from_handle(handle: M::ManagedMapHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedMapHandle) -> Self { ManagedMap { handle } } @@ -35,7 +35,7 @@ impl ManagedType for ManagedMap { impl ManagedMap { pub fn new() -> Self { let new_handle = M::managed_type_impl().mm_new(); - ManagedMap::from_handle(new_handle) + unsafe { ManagedMap::from_handle(new_handle) } } } @@ -48,10 +48,15 @@ impl Default for ManagedMap { impl ManagedMap { pub fn get(&self, key: &ManagedBuffer) -> ManagedBuffer { - let new_handle: M::ManagedBufferHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mm_get(self.handle.clone(), key.handle.clone(), new_handle.clone()); - ManagedBuffer::from_handle(new_handle) + unsafe { + let result = ManagedBuffer::new_uninit(); + M::managed_type_impl().mm_get( + self.handle.clone(), + key.handle.clone(), + result.get_handle(), + ); + result + } } pub fn put(&mut self, key: &ManagedBuffer, value: &ManagedBuffer) { @@ -70,7 +75,7 @@ impl ManagedMap { key.handle.clone(), new_handle.clone(), ); - ManagedBuffer::from_handle(new_handle) + unsafe { ManagedBuffer::from_handle(new_handle) } } pub fn contains(&self, key: &ManagedBuffer) -> bool { diff --git a/framework/base/src/types/managed/managed_type_trait.rs b/framework/base/src/types/managed/managed_type_trait.rs index e7b97e2ab6..ca9210d594 100644 --- a/framework/base/src/types/managed/managed_type_trait.rs +++ b/framework/base/src/types/managed/managed_type_trait.rs @@ -7,12 +7,12 @@ pub trait ManagedType: Sized { type OwnHandle: HandleConstraints; #[doc(hidden)] - fn from_handle(handle: Self::OwnHandle) -> Self; + unsafe fn from_handle(handle: Self::OwnHandle) -> Self; fn get_handle(&self) -> Self::OwnHandle; #[doc(hidden)] - fn from_raw_handle(handle: RawHandle) -> Self { + unsafe fn from_raw_handle(handle: RawHandle) -> Self { Self::from_handle(Self::OwnHandle::new(handle)) } diff --git a/framework/base/src/types/managed/multi_value/multi_value_encoded.rs b/framework/base/src/types/managed/multi_value/multi_value_encoded.rs index 04dbde9357..31d9a25e64 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_encoded.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_encoded.rs @@ -115,7 +115,7 @@ where M: ManagedTypeApi, { pub fn to_arg_buffer(&self) -> ManagedArgBuffer { - ManagedArgBuffer::from_handle(self.raw_buffers.get_handle()) + unsafe { ManagedArgBuffer::from_handle(self.raw_buffers.get_handle()) } } } diff --git a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs index e628ba8421..6ad36a25e8 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs @@ -46,7 +46,7 @@ where type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { Self(ManagedVec::from_handle(handle)) } diff --git a/framework/base/src/types/managed/wrapped/big_uint.rs b/framework/base/src/types/managed/wrapped/big_uint.rs index dfba440073..fc717e70c6 100644 --- a/framework/base/src/types/managed/wrapped/big_uint.rs +++ b/framework/base/src/types/managed/wrapped/big_uint.rs @@ -26,7 +26,7 @@ pub struct BigUint { impl ManagedType for BigUint { type OwnHandle = M::BigIntHandle; - fn from_handle(handle: M::BigIntHandle) -> Self { + unsafe fn from_handle(handle: M::BigIntHandle) -> Self { BigUint { value: BigInt::from_handle(handle), } @@ -66,6 +66,17 @@ impl From<&ManagedBuffer> for BigUint { } impl BigUint { + /// Creates a new object, without initializing it. + /// + /// ## Safety + /// + /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read. + pub unsafe fn new_uninit() -> Self { + BigUint { + value: BigInt::new_uninit(), + } + } + pub(crate) fn set_value(handle: M::BigIntHandle, value: T) where T: TryInto + num_traits::Unsigned, @@ -77,9 +88,11 @@ impl BigUint { where T: TryInto + num_traits::Unsigned, { - let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - Self::set_value(handle.clone(), value); - BigUint::from_handle(handle) + unsafe { + let result = Self::new_uninit(); + Self::set_value(result.get_handle(), value); + result + } } pub(crate) fn make_temp(handle: RawHandle, value: T) -> M::BigIntHandle @@ -173,9 +186,11 @@ impl Default for BigUint { impl BigUint { #[inline] pub fn zero() -> Self { - let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bi_set_int64(handle.clone(), 0); - BigUint::from_handle(handle) + unsafe { + let result = Self::new_uninit(); + M::managed_type_impl().bi_set_int64(result.get_handle(), 0); + result + } } pub fn zero_ref() -> ManagedRef<'static, M, BigUint> { @@ -199,9 +214,11 @@ impl BigUint { pub fn from_bytes_be(bytes: &[u8]) -> Self { let mb_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); M::managed_type_impl().mb_overwrite(mb_handle.clone(), bytes); - let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mb_to_big_int_unsigned(mb_handle, handle.clone()); - BigUint::from_handle(handle) + unsafe { + let result = Self::new_uninit(); + M::managed_type_impl().mb_to_big_int_unsigned(mb_handle, result.get_handle()); + result + } } #[inline] @@ -217,7 +234,7 @@ impl BigUint { let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl() .mb_to_big_int_unsigned(managed_buffer.handle.clone(), handle.clone()); - BigUint::from_handle(handle) + unsafe { BigUint::from_handle(handle) } } #[inline] @@ -226,7 +243,7 @@ impl BigUint { use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl() .mb_from_big_int_unsigned(self.value.handle.clone(), mb_handle.clone()); - ManagedBuffer::from_handle(mb_handle) + unsafe { ManagedBuffer::from_handle(mb_handle) } } } @@ -237,7 +254,7 @@ impl BigUint { let api = M::managed_type_impl(); let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); api.bi_sqrt(result_handle.clone(), self.value.handle.clone()); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } #[must_use] @@ -249,7 +266,7 @@ impl BigUint { self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } /// The whole part of the base-2 logarithm. @@ -310,7 +327,7 @@ impl Clone for BigUint { clone_handle.clone(), self.value.handle.clone(), ); - BigUint::from_handle(clone_handle) + unsafe { BigUint::from_handle(clone_handle) } } } @@ -376,9 +393,9 @@ impl SCDisplay for BigUint { fn fmt(&self, f: &mut F) { let str_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); M::managed_type_impl().bi_to_string(self.value.handle.clone(), str_handle.clone()); - f.append_managed_buffer(&ManagedBuffer::from_handle( - str_handle.cast_or_signal_error::(), - )); + let cast_handle = str_handle.cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); } } diff --git a/framework/base/src/types/managed/wrapped/big_uint_operators.rs b/framework/base/src/types/managed/wrapped/big_uint_operators.rs index 934079eef7..a4becdcf10 100644 --- a/framework/base/src/types/managed/wrapped/big_uint_operators.rs +++ b/framework/base/src/types/managed/wrapped/big_uint_operators.rs @@ -18,7 +18,7 @@ macro_rules! binary_operator { self.value.handle.clone(), other.value.handle.clone(), ); - BigUint::from_handle(self.value.handle.clone()) + self } } @@ -33,7 +33,7 @@ macro_rules! binary_operator { self.value.handle.clone(), other.value.handle.clone(), ); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } } @@ -46,7 +46,7 @@ macro_rules! binary_operator { self.value.handle.clone(), other.value.handle.clone(), ); - BigUint::from_handle(self.value.handle.clone()) + self } } @@ -60,7 +60,7 @@ macro_rules! binary_operator { self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(self.value.handle.clone()) + self } } @@ -77,7 +77,7 @@ macro_rules! binary_operator { self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } } @@ -91,7 +91,7 @@ macro_rules! binary_operator { self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(self.value.handle.clone()) + self } } @@ -108,7 +108,7 @@ macro_rules! binary_operator { self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } } }; @@ -207,7 +207,7 @@ macro_rules! shift_traits { self.value.handle.clone(), rhs, ); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } } }; diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index 19506645a2..97bf533e69 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -58,7 +58,7 @@ impl EgldOrEsdtTokenIdentifier { pub fn from_opt_raw_handle(opt_handle: Option) -> Self { match opt_handle { - Some(handle) => Self::esdt(TokenIdentifier::from_handle(handle)), + Some(handle) => Self::esdt(unsafe { TokenIdentifier::from_handle(handle) }), None => Self::egld(), } } @@ -240,9 +240,12 @@ impl TypeAbi for EgldOrEsdtTokenIdentifier { impl SCDisplay for EgldOrEsdtTokenIdentifier { fn fmt(&self, f: &mut F) { if let Some(token_identifier) = self.data.as_option() { - f.append_managed_buffer(&ManagedBuffer::from_handle( - token_identifier.get_handle().cast_or_signal_error::(), - )); + let cast_handle = token_identifier.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); + // f.append_managed_buffer(&ManagedBuffer::from_handle( + // token_identifier.get_handle().cast_or_signal_error::(), + // )); } else { f.append_bytes(Self::EGLD_REPRESENTATION); } @@ -254,9 +257,12 @@ const EGLD_REPRESENTATION_HEX: &[u8] = b"45474C44"; impl SCLowerHex for EgldOrEsdtTokenIdentifier { fn fmt(&self, f: &mut F) { if let Some(token_identifier) = self.data.as_option() { - f.append_managed_buffer_lower_hex(&ManagedBuffer::from_handle( - token_identifier.get_handle().cast_or_signal_error::(), - )); + let cast_handle = token_identifier.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer_lower_hex(&wrap_cast); + // f.append_managed_buffer_lower_hex(&ManagedBuffer::from_handle( + // token_identifier.get_handle().cast_or_signal_error::(), + // )); } else { f.append_bytes(EGLD_REPRESENTATION_HEX); } diff --git a/framework/base/src/types/managed/wrapped/managed_address.rs b/framework/base/src/types/managed/wrapped/managed_address.rs index 18473419e4..a12200a039 100644 --- a/framework/base/src/types/managed/wrapped/managed_address.rs +++ b/framework/base/src/types/managed/wrapped/managed_address.rs @@ -2,7 +2,7 @@ use core::convert::{TryFrom, TryInto}; use crate::{ abi::{TypeAbi, TypeAbiFrom, TypeName}, - api::ManagedTypeApi, + api::{use_raw_handle, ManagedTypeApi, RawHandle}, codec::{ DecodeError, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, @@ -11,6 +11,8 @@ use crate::{ types::{heap::Address, ManagedBuffer, ManagedByteArray, ManagedType}, }; +use super::ManagedRef; + #[repr(transparent)] #[derive(Clone)] pub struct ManagedAddress { @@ -49,6 +51,28 @@ where } } + /// Creates a new object, without initializing it. + /// + /// ## Safety + /// + /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read. + pub unsafe fn new_uninit() -> Self { + ManagedAddress { + bytes: ManagedByteArray::new_uninit(), + } + } + + /// Creates a shared managed reference to a given raw handle. + /// + /// ## Safety + /// + /// The reference points to a shared value. Make sure the handle is not leaked. + pub unsafe fn temp_const_ref( + raw_handle: RawHandle, + ) -> ManagedRef<'static, M, ManagedAddress> { + ManagedRef::wrap_handle(use_raw_handle(raw_handle)) + } + #[inline] pub fn as_managed_buffer(&self) -> &ManagedBuffer { self.bytes.as_managed_buffer() @@ -133,7 +157,7 @@ where type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { ManagedAddress { bytes: ManagedByteArray::from_handle(handle), } diff --git a/framework/base/src/types/managed/wrapped/managed_byte_array.rs b/framework/base/src/types/managed/wrapped/managed_byte_array.rs index 9d7b15d2b7..5ef3e661b7 100644 --- a/framework/base/src/types/managed/wrapped/managed_byte_array.rs +++ b/framework/base/src/types/managed/wrapped/managed_byte_array.rs @@ -35,7 +35,7 @@ where type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { ManagedByteArray { buffer: ManagedBuffer::from_handle(handle), } @@ -85,6 +85,17 @@ where } } + /// Creates a new object, without initializing it. + /// + /// ## Safety + /// + /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read. + pub unsafe fn new_uninit() -> Self { + ManagedByteArray { + buffer: ManagedBuffer::new_uninit(), + } + } + /// Number of items. #[inline] pub fn len(&self) -> usize { diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs index 41f173a50a..698b2fbbee 100644 --- a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs @@ -2,7 +2,7 @@ use super::decimals::{ConstDecimals, Decimals}; use super::ManagedDecimalSigned; use super::{ManagedDecimal, NumDecimals}; -use crate::proxy_imports::ManagedType; +use crate::types::ManagedRef; use crate::{ api::ManagedTypeApi, contract_base::ErrorHelper, @@ -104,7 +104,7 @@ impl ManagedDecimalSigned { return None; } - let bu = BigUint::from_handle(self.data.handle.clone()); + let bu = unsafe { ManagedRef::wrap_handle(self.data.handle.clone()) }; compute_ln(&bu, self.decimals.num_decimals()) } @@ -118,7 +118,8 @@ impl ManagedDecimalSigned { return None; } - let bu = BigUint::from_handle(self.data.handle.clone()); + let bu = unsafe { ManagedRef::wrap_handle(self.data.handle.clone()) }; + // let bu = BigUint::from_handle(self.data.handle.clone()); compute_log2(&bu, self.decimals.num_decimals()) } } diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_signed.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_signed.rs index c8ee403f37..0338417f82 100644 --- a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_signed.rs +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_signed.rs @@ -6,7 +6,7 @@ use crate::{ }, err_msg, formatter::{FormatBuffer, FormatByteReceiver, SCDisplay}, - types::{BigFloat, BigInt, BigUint, ManagedBuffer, ManagedType, Sign}, + types::{BigFloat, BigInt, BigUint, Sign}, }; use alloc::string::ToString; @@ -354,15 +354,15 @@ pub(super) fn managed_decimal_fmt( if len > num_dec { let temp_str_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_2); + let cast_handle = temp_str_handle.clone().cast_or_signal_error::(); + let temp_str_ref = unsafe { ManagedRef::wrap_handle(cast_handle) }; let _ = M::managed_type_impl().mb_copy_slice( full_str_handle.clone(), 0, len - num_dec, temp_str_handle.clone(), ); - f.append_managed_buffer(&ManagedBuffer::from_raw_handle( - temp_str_handle.get_raw_handle(), - )); + f.append_managed_buffer(&temp_str_ref); f.append_bytes(b"."); let _ = M::managed_type_impl().mb_copy_slice( full_str_handle.clone(), @@ -370,17 +370,15 @@ pub(super) fn managed_decimal_fmt( num_dec, temp_str_handle.clone(), ); - f.append_managed_buffer(&ManagedBuffer::from_raw_handle( - temp_str_handle.get_raw_handle(), - )); + f.append_managed_buffer(&temp_str_ref); } else { f.append_bytes(b"0."); for _ in len..num_dec { f.append_bytes(b"0"); } - f.append_managed_buffer(&ManagedBuffer::from_raw_handle( - full_str_handle.get_raw_handle(), - )); + let cast_handle = full_str_handle.clone().cast_or_signal_error::(); + let full_str_ref = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&full_str_ref); } } diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index e448ae8e88..e433913835 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -143,7 +143,7 @@ where F: FnOnce(Context, &T) -> R, { if self.is_some() { - f(context, &T::from_handle(self.handle.clone())) + f(context, unsafe { &T::from_handle(self.handle.clone()) }) } else { default(context) } @@ -158,7 +158,7 @@ where #[allow(clippy::redundant_clone)] // the clone is not redundant fn clone(&self) -> Self { if self.is_some() { - Self::some(T::from_handle(self.handle.clone()).clone()) + Self::some(unsafe { T::from_handle(self.handle.clone()) }.clone()) } else { Self::none() } @@ -177,7 +177,10 @@ where return true; } if self.is_some() && other.is_some() { - return T::from_handle(self.handle.clone()) == T::from_handle(other.handle.clone()); + unsafe { + return ManagedRef::<'_, _, T>::wrap_handle(self.handle.clone()) + == ManagedRef::<'_, _, T>::wrap_handle(other.handle.clone()); + } } false } @@ -327,7 +330,7 @@ where fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if self.is_some() { f.debug_tuple("ManagedOption::Some") - .field(&T::from_handle(self.handle.clone())) + .field(unsafe { &T::from_handle(self.handle.clone()) }) .finish() } else { f.write_str("ManagedOption::None") diff --git a/framework/base/src/types/managed/wrapped/managed_ref.rs b/framework/base/src/types/managed/wrapped/managed_ref.rs index 143d79e1d4..ef0e20fb9f 100644 --- a/framework/base/src/types/managed/wrapped/managed_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_ref.rs @@ -34,7 +34,7 @@ where /// Will completely disregard lifetimes, use with care. #[doc(hidden)] - pub(crate) unsafe fn wrap_handle(handle: T::OwnHandle) -> Self { + pub unsafe fn wrap_handle(handle: T::OwnHandle) -> Self { Self { _phantom_m: PhantomData, _phantom_t: PhantomData, diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index eb79ffebcd..582054e6ec 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -45,7 +45,7 @@ where type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { ManagedVec { buffer: ManagedBuffer::from_handle(handle), _phantom: PhantomData, @@ -768,4 +768,3 @@ where } } } - diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 8e7dc5512a..8e88624d75 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -192,7 +192,7 @@ macro_rules! impl_managed_type { fn from_byte_reader(reader: Reader) -> Self { let handle = <$ty as ManagedType>::OwnHandle::from_byte_reader(reader); - $ty::from_handle(handle) + unsafe { $ty::from_handle(handle) } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( @@ -226,7 +226,7 @@ where fn from_byte_reader(reader: Reader) -> Self { let handle = >::OwnHandle::from_byte_reader(reader); - Self::from_handle(handle) + unsafe { Self::from_handle(handle) } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( @@ -255,7 +255,7 @@ where fn from_byte_reader(reader: Reader) -> Self { let handle = M::ManagedBufferHandle::from_byte_reader(reader); - Self::from_handle(handle) + unsafe { Self::from_handle(handle) } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( diff --git a/framework/base/src/types/managed/wrapped/token_identifier.rs b/framework/base/src/types/managed/wrapped/token_identifier.rs index 69481772e0..10c92475a3 100644 --- a/framework/base/src/types/managed/wrapped/token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/token_identifier.rs @@ -9,7 +9,7 @@ use crate::{ types::{ManagedBuffer, ManagedType}, }; -use super::EgldOrEsdtTokenIdentifier; +use super::{EgldOrEsdtTokenIdentifier, ManagedRef}; /// Specialized type for handling token identifiers. /// It wraps a BoxedBytes with the full ASCII name of the token. @@ -26,7 +26,7 @@ impl ManagedType for TokenIdentifier { type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { TokenIdentifier { buffer: ManagedBuffer::from_handle(handle), } @@ -194,17 +194,17 @@ impl TypeAbi for TokenIdentifier { impl SCDisplay for TokenIdentifier { fn fmt(&self, f: &mut F) { - f.append_managed_buffer(&ManagedBuffer::from_handle( - self.buffer.get_handle().cast_or_signal_error::(), - )); + let cast_handle = self.buffer.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); } } impl SCLowerHex for TokenIdentifier { fn fmt(&self, f: &mut F) { - f.append_managed_buffer_lower_hex(&ManagedBuffer::from_handle( - self.buffer.get_handle().cast_or_signal_error::(), - )); + let cast_handle = self.buffer.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer_lower_hex(&wrap_cast); } } From 9669110b9a32bb5454f950fed3af804ad2f4a9f6 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sun, 10 Nov 2024 12:57:18 +0200 Subject: [PATCH 004/133] test fix --- tools/rust-debugger/format-tests/src/format_tests.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/rust-debugger/format-tests/src/format_tests.rs b/tools/rust-debugger/format-tests/src/format_tests.rs index 2c72e4acda..755bbbda17 100644 --- a/tools/rust-debugger/format-tests/src/format_tests.rs +++ b/tools/rust-debugger/format-tests/src/format_tests.rs @@ -181,7 +181,7 @@ fn main() { let invalid_handle = DebugHandle::from(-1000); let biguint_with_invalid_handle: BigUint = - BigUint::from_handle(invalid_handle.clone()); + unsafe { BigUint::from_handle(invalid_handle.clone()) }; push!( to_check, biguint_with_invalid_handle, @@ -189,7 +189,7 @@ fn main() { ); let big_float_with_invalid_handle: BigFloat = - BigFloat::from_handle(invalid_handle.clone()); + unsafe { BigFloat::from_handle(invalid_handle.clone()) }; push!( to_check, big_float_with_invalid_handle, @@ -197,7 +197,7 @@ fn main() { ); let managed_buffer_with_invalid_handle: ManagedBuffer = - ManagedBuffer::from_handle(invalid_handle.clone()); + unsafe { ManagedBuffer::from_handle(invalid_handle.clone()) }; push!( to_check, managed_buffer_with_invalid_handle, @@ -205,7 +205,7 @@ fn main() { ); let token_identifier_with_invalid_handle: TokenIdentifier = - TokenIdentifier::from_handle(invalid_handle.clone()); + unsafe { TokenIdentifier::from_handle(invalid_handle.clone()) }; push!( to_check, token_identifier_with_invalid_handle, @@ -213,7 +213,7 @@ fn main() { ); let optional_value_some_with_invalid_handle: OptionalValue> = - OptionalValue::Some(BigUint::from_handle(invalid_handle.clone())); + OptionalValue::Some(unsafe { BigUint::from_handle(invalid_handle.clone()) }); push!( to_check, optional_value_some_with_invalid_handle, From 6e5b66a6630d11851a2f769aa6c4281210677a62 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sun, 10 Nov 2024 22:24:58 +0200 Subject: [PATCH 005/133] ManagedType from_handle refactor - BigFloat --- framework/base/src/io/arg_de_input.rs | 4 - .../base/src/types/managed/basic/big_float.rs | 127 ++++++++++-------- .../managed/basic/big_float_operators.rs | 30 +++-- 3 files changed, 90 insertions(+), 71 deletions(-) diff --git a/framework/base/src/io/arg_de_input.rs b/framework/base/src/io/arg_de_input.rs index 7c84d9cbb9..1b5502b6fa 100644 --- a/framework/base/src/io/arg_de_input.rs +++ b/framework/base/src/io/arg_de_input.rs @@ -64,10 +64,6 @@ where .load_argument_big_int_unsigned(self.arg_index, result.get_handle()); result } - - // let bi_handle: AA::BigIntHandle = use_raw_handle(AA::static_var_api_impl().next_handle()); - // AA::argument_api_impl().load_argument_big_int_unsigned(self.arg_index, bi_handle.clone()); - // BigUint::from_handle(bi_handle) } } diff --git a/framework/base/src/types/managed/basic/big_float.rs b/framework/base/src/types/managed/basic/big_float.rs index 8361cb4b79..f5a78b307a 100644 --- a/framework/base/src/types/managed/basic/big_float.rs +++ b/framework/base/src/types/managed/basic/big_float.rs @@ -102,31 +102,31 @@ big_float_conv_num! {i8} impl BigFloat { pub fn neg(&self) -> Self { - let new_bf_handle: M::BigFloatHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bf_neg(new_bf_handle.clone(), self.handle.clone()); - unsafe { BigFloat::from_handle(new_bf_handle) } + unsafe { + let result = BigFloat::new_uninit(); + M::managed_type_impl().bf_neg(result.get_handle(), self.handle.clone()); + result + } } pub fn abs(&self) -> Self { - let new_bf_handle: M::BigFloatHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bf_abs(new_bf_handle.clone(), self.handle.clone()); - unsafe { BigFloat::from_handle(new_bf_handle) } + unsafe { + let result = BigFloat::new_uninit(); + M::managed_type_impl().bf_abs(result.get_handle(), self.handle.clone()); + result + } } - pub fn from_big_uint(big_uint: &BigUint) -> Self { - let new_bf_handle: M::BigFloatHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bf_set_bi(new_bf_handle.clone(), big_uint.value.handle.clone()); - unsafe { BigFloat::from_handle(new_bf_handle) } + pub fn from_big_int(big_int: &BigInt) -> Self { + unsafe { + let result = BigFloat::new_uninit(); + M::managed_type_impl().bf_set_bi(result.get_handle(), big_int.handle.clone()); + result + } } - pub fn from_big_int(big_int: &BigInt) -> Self { - let new_bf_handle: M::BigFloatHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bf_set_bi(new_bf_handle.clone(), big_int.handle.clone()); - unsafe { BigFloat::from_handle(new_bf_handle) } + pub fn from_big_uint(big_uint: &BigUint) -> Self { + Self::from_big_int(big_uint.as_big_int()) } #[inline] @@ -156,24 +156,27 @@ impl BigFloat { } pub fn trunc(&self) -> BigInt { - let result: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - let api = M::managed_type_impl(); - api.bf_trunc(result.clone(), self.handle.clone()); - unsafe { BigInt::from_handle(result) } + unsafe { + let result = BigInt::new_uninit(); + M::managed_type_impl().bf_trunc(result.get_handle(), self.handle.clone()); + result + } } pub fn floor(&self) -> BigInt { - let result: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - let api = M::managed_type_impl(); - api.bf_floor(result.clone(), self.handle.clone()); - unsafe { BigInt::from_handle(result) } + unsafe { + let result = BigInt::new_uninit(); + M::managed_type_impl().bf_floor(result.get_handle(), self.handle.clone()); + result + } } pub fn ceil(&self) -> BigInt { - let result: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - let api = M::managed_type_impl(); - api.bf_ceil(result.clone(), self.handle.clone()); - unsafe { BigInt::from_handle(result) } + unsafe { + let result = BigInt::new_uninit(); + M::managed_type_impl().bf_ceil(result.get_handle(), self.handle.clone()); + result + } } pub fn to_fixed_point(&self, denominator: &BigFloat) -> BigInt { @@ -258,34 +261,48 @@ impl BigFloat { } pub fn from_buffer(managed_buffer: &ManagedBuffer) -> Self { - let new_bf_handle: M::BigFloatHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl() - .mb_to_big_float(managed_buffer.handle.clone(), new_bf_handle.clone()); - unsafe { BigFloat::from_handle(new_bf_handle) } + unsafe { + let result = BigFloat::new_uninit(); + M::managed_type_impl() + .mb_to_big_float(managed_buffer.handle.clone(), result.get_handle()); + result + } } pub fn to_buffer(&self) -> ManagedBuffer { - let new_man_buf_handle: M::ManagedBufferHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mb_from_big_float(self.handle.clone(), new_man_buf_handle.clone()); - unsafe { ManagedBuffer::from_handle(new_man_buf_handle) } + unsafe { + let result = ManagedBuffer::new_uninit(); + M::managed_type_impl().mb_from_big_float(self.get_handle(), result.get_handle()); + result + } + } + + /// Creates a new object, without initializing it. + /// + /// ## Safety + /// + /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read. + pub unsafe fn new_uninit() -> Self { + let new_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); + BigFloat::from_handle(new_handle) } } impl BigFloat { pub fn sqrt(&self) -> Self { - let api = M::managed_type_impl(); - let new_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - api.bf_sqrt(new_handle.clone(), self.handle.clone()); - unsafe { BigFloat::from_handle(new_handle) } + unsafe { + let result = BigFloat::new_uninit(); + M::managed_type_impl().bf_sqrt(result.get_handle(), self.handle.clone()); + result + } } pub fn pow(&self, exp: i32) -> Self { - let api = M::managed_type_impl(); - let new_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - api.bf_pow(new_handle.clone(), self.handle.clone(), exp); - unsafe { BigFloat::from_handle(new_handle) } + unsafe { + let result = BigFloat::new_uninit(); + M::managed_type_impl().bf_pow(result.get_handle(), self.handle.clone(), exp); + result + } } /// Returns the sign of the `BigFloat` as a `Sign`. @@ -299,9 +316,11 @@ impl BigFloat { /// Returns the magnitude of the `BigFloat` pub fn magnitude(&self) -> BigFloat { - let result: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bf_abs(result.clone(), self.handle.clone()); - unsafe { BigFloat::from_handle(result) } + unsafe { + let result = BigFloat::new_uninit(); + M::managed_type_impl().bf_abs(result.get_handle(), self.handle.clone()); + result + } } /// Convert this `BigFloat` into its `Sign` and its magnitude, @@ -341,9 +360,11 @@ impl BigFloat { impl Clone for BigFloat { fn clone(&self) -> Self { - let new_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bf_clone(new_handle.clone(), self.handle.clone()); - unsafe { BigFloat::from_handle(new_handle) } + unsafe { + let result = BigFloat::new_uninit(); + M::managed_type_impl().bf_clone(result.get_handle(), self.handle.clone()); + result + } } } diff --git a/framework/base/src/types/managed/basic/big_float_operators.rs b/framework/base/src/types/managed/basic/big_float_operators.rs index 7333a69ebe..e8d27016a8 100644 --- a/framework/base/src/types/managed/basic/big_float_operators.rs +++ b/framework/base/src/types/managed/basic/big_float_operators.rs @@ -1,6 +1,6 @@ use super::BigFloat; use crate::{ - api::{use_raw_handle, BigFloatApiImpl, ManagedTypeApi, StaticVarApiImpl}, + api::{BigFloatApiImpl, ManagedTypeApi}, types::managed::managed_type_trait::ManagedType, }; use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; @@ -16,7 +16,7 @@ macro_rules! binary_operator { self.handle.clone(), other.handle.clone(), ); - unsafe { BigFloat::from_handle(self.handle.clone()) } + self } } @@ -24,14 +24,15 @@ macro_rules! binary_operator { type Output = BigFloat; fn $method(self, other: &BigFloat) -> BigFloat { - let result_handle: M::BigFloatHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().$api_func( - result_handle.clone(), - self.handle.clone(), - other.handle.clone(), - ); - unsafe { BigFloat::from_handle(result_handle) } + unsafe { + let result = BigFloat::new_uninit(); + M::managed_type_impl().$api_func( + result.get_handle(), + self.handle.clone(), + other.handle.clone(), + ); + result + } } } }; @@ -79,9 +80,10 @@ impl Neg for BigFloat { type Output = BigFloat; fn neg(self) -> Self::Output { - let result_handle: M::BigFloatHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bf_neg(result_handle.clone(), self.handle); - unsafe { BigFloat::from_handle(result_handle) } + unsafe { + let result = BigFloat::new_uninit(); + M::managed_type_impl().bf_neg(result.get_handle(), self.handle.clone()); + result + } } } From 11898eaf0c4869cacaf254d261bd1de75826e9cd Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 11 Nov 2024 13:17:28 +0200 Subject: [PATCH 006/133] ManagedType from_handle refactor - BigInt/BigUint --- .../base/src/types/managed/basic/big_float.rs | 9 +- .../base/src/types/managed/basic/big_int.rs | 86 +++++++++++-------- .../types/managed/basic/big_int_operators.rs | 11 +-- .../src/types/managed/basic/managed_map.rs | 19 ++-- .../src/types/managed/wrapped/big_uint.rs | 61 +++++-------- .../managed/wrapped/big_uint_operators.rs | 82 +++++++++--------- 6 files changed, 135 insertions(+), 133 deletions(-) diff --git a/framework/base/src/types/managed/basic/big_float.rs b/framework/base/src/types/managed/basic/big_float.rs index f5a78b307a..634d76f67d 100644 --- a/framework/base/src/types/managed/basic/big_float.rs +++ b/framework/base/src/types/managed/basic/big_float.rs @@ -85,10 +85,11 @@ macro_rules! big_float_conv_num { impl From<$num_ty> for BigFloat { #[inline] fn from(value: $num_ty) -> Self { - let new_bf_handle: M::BigFloatHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bf_set_i64(new_bf_handle.clone(), value as i64); - unsafe { BigFloat::from_handle(new_bf_handle) } + unsafe { + let result = BigFloat::new_uninit(); + M::managed_type_impl().bf_set_i64(result.get_handle(), value as i64); + result + } } } }; diff --git a/framework/base/src/types/managed/basic/big_int.rs b/framework/base/src/types/managed/basic/big_int.rs index 9727d81dd5..13c3b965af 100644 --- a/framework/base/src/types/managed/basic/big_int.rs +++ b/framework/base/src/types/managed/basic/big_int.rs @@ -108,10 +108,11 @@ macro_rules! big_int_conv_num { impl From<$num_ty> for BigInt { #[inline] fn from(value: $num_ty) -> Self { - let handle: M::BigIntHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - Self::set_value(handle.clone(), value); - unsafe { BigInt::from_handle(handle) } + unsafe { + let result = BigInt::new_uninit(); + Self::set_value(result.get_handle(), value); + result + } } } @@ -167,9 +168,11 @@ impl From for BigInt { impl BigInt { #[inline] pub fn zero() -> Self { - let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bi_set_int64(handle.clone(), 0); - unsafe { BigInt::from_handle(handle) } + unsafe { + let result = BigInt::new_uninit(); + M::managed_type_impl().bi_set_int64(result.get_handle(), 0); + result + } } #[inline] @@ -186,9 +189,11 @@ impl BigInt { pub fn from_signed_bytes_be(bytes: &[u8]) -> Self { let mb_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); M::managed_type_impl().mb_overwrite(mb_handle.clone(), bytes); - let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mb_to_big_int_signed(mb_handle, handle.clone()); - unsafe { BigInt::from_handle(handle) } + unsafe { + let result = BigInt::new_uninit(); + M::managed_type_impl().mb_to_big_int_signed(mb_handle, result.get_handle()); + result + } } #[inline] @@ -200,41 +205,47 @@ impl BigInt { #[inline] pub fn from_signed_bytes_be_buffer(managed_buffer: &ManagedBuffer) -> Self { - let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mb_to_big_int_signed(managed_buffer.handle.clone(), handle.clone()); - unsafe { BigInt::from_handle(handle) } + unsafe { + let result = BigInt::new_uninit(); + M::managed_type_impl() + .mb_to_big_int_signed(managed_buffer.handle.clone(), result.get_handle()); + result + } } #[inline] pub fn to_signed_bytes_be_buffer(&self) -> ManagedBuffer { - let mb_handle: M::ManagedBufferHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mb_from_big_int_signed(self.handle.clone(), mb_handle.clone()); - unsafe { ManagedBuffer::from_handle(mb_handle) } + unsafe { + let result = ManagedBuffer::new_uninit(); + M::managed_type_impl().mb_from_big_int_signed(self.handle.clone(), result.get_handle()); + result + } } } impl Clone for BigInt { fn clone(&self) -> Self { let api = M::managed_type_impl(); - let clone_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - api.bi_set_int64(clone_handle.clone(), 0); - api.bi_add( - clone_handle.clone(), - clone_handle.clone(), - self.handle.clone(), - ); - unsafe { BigInt::from_handle(clone_handle) } + unsafe { + let result = BigInt::new_uninit(); + api.bi_set_int64(result.get_handle(), 0); + api.bi_add( + result.get_handle(), + result.get_handle(), + self.handle.clone(), + ); + result + } } } impl BigInt { pub fn from_biguint(sign: Sign, unsigned: BigUint) -> Self { - let api = M::managed_type_impl(); + let result = unsigned.into_big_int(); if sign.is_minus() { - api.bi_neg(unsigned.value.handle.clone(), unsigned.value.handle.clone()); + M::managed_type_impl().bi_neg(result.handle.clone(), result.handle.clone()); } - unsafe { BigInt::from_handle(unsigned.value.handle) } + result } /// Returns the sign of the `BigInt` as a `Sign`. @@ -249,10 +260,11 @@ impl BigInt { /// Returns the magnitude of the `BigInt` as a `BigUint`. pub fn magnitude(&self) -> BigUint { - let api = M::managed_type_impl(); - let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - api.bi_abs(result_handle.clone(), self.handle.clone()); - unsafe { BigUint::from_handle(result_handle) } + unsafe { + let result = BigUint::new_uninit(); + M::managed_type_impl().bi_abs(result.get_handle(), self.get_handle()); + result + } } /// Convert this `BigInt` into its `Sign` and `BigUint` magnitude, @@ -267,7 +279,7 @@ impl BigInt { /// /// If the number is negative, undefined behavior might occur further down the execution. pub unsafe fn into_big_uint_unchecked(self) -> BigUint { - BigUint::from_handle(self.handle) + BigUint { value: self } } /// Converts this `BigInt` into a `BigUint`, if it's not negative. @@ -342,10 +354,12 @@ impl TopDecode for BigInt { impl BigInt { #[must_use] pub fn pow(&self, exp: u32) -> Self { - let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); let exp_handle = BigUint::::make_temp(const_handles::BIG_INT_TEMPORARY_1, exp); - M::managed_type_impl().bi_pow(result_handle.clone(), self.handle.clone(), exp_handle); - unsafe { BigInt::from_handle(result_handle) } + unsafe { + let result = BigInt::new_uninit(); + M::managed_type_impl().bi_pow(result.get_handle(), self.get_handle(), exp_handle); + result + } } } diff --git a/framework/base/src/types/managed/basic/big_int_operators.rs b/framework/base/src/types/managed/basic/big_int_operators.rs index 0cf00c66e6..9edf670cb9 100644 --- a/framework/base/src/types/managed/basic/big_int_operators.rs +++ b/framework/base/src/types/managed/basic/big_int_operators.rs @@ -3,7 +3,7 @@ use core::ops::{ }; use crate::{ - api::{use_raw_handle, BigIntApiImpl, ManagedTypeApi, StaticVarApiImpl}, + api::{BigIntApiImpl, ManagedTypeApi}, types::{BigInt, BigUint, ManagedType, Sign}, }; @@ -118,9 +118,10 @@ impl Neg for BigInt { type Output = BigInt; fn neg(self) -> Self::Output { - let api = M::managed_type_impl(); - let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - api.bi_neg(result_handle.clone(), self.handle); - unsafe { BigInt::from_handle(result_handle) } + unsafe { + let result = BigInt::new_uninit(); + M::managed_type_impl().bi_neg(result.get_handle(), self.handle); + result + } } } diff --git a/framework/base/src/types/managed/basic/managed_map.rs b/framework/base/src/types/managed/basic/managed_map.rs index 0d7cc2f1b4..139f93cf9c 100644 --- a/framework/base/src/types/managed/basic/managed_map.rs +++ b/framework/base/src/types/managed/basic/managed_map.rs @@ -1,5 +1,5 @@ use crate::{ - api::{use_raw_handle, ManagedMapApiImpl, ManagedTypeApi, StaticVarApiImpl}, + api::{ManagedMapApiImpl, ManagedTypeApi}, types::ManagedType, }; @@ -68,14 +68,15 @@ impl ManagedMap { } pub fn remove(&mut self, key: &ManagedBuffer) -> ManagedBuffer { - let new_handle: M::ManagedBufferHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mm_remove( - self.handle.clone(), - key.handle.clone(), - new_handle.clone(), - ); - unsafe { ManagedBuffer::from_handle(new_handle) } + unsafe { + let result = ManagedBuffer::new_uninit(); + M::managed_type_impl().mm_remove( + self.handle.clone(), + key.handle.clone(), + result.get_handle(), + ); + result + } } pub fn contains(&self, key: &ManagedBuffer) -> bool { diff --git a/framework/base/src/types/managed/wrapped/big_uint.rs b/framework/base/src/types/managed/wrapped/big_uint.rs index fc717e70c6..344842c2a3 100644 --- a/framework/base/src/types/managed/wrapped/big_uint.rs +++ b/framework/base/src/types/managed/wrapped/big_uint.rs @@ -4,7 +4,7 @@ use crate::{ abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{ const_handles, use_raw_handle, BigIntApiImpl, HandleConstraints, ManagedBufferApiImpl, - ManagedTypeApi, ManagedTypeApiImpl, RawHandle, StaticVarApiImpl, + ManagedTypeApi, ManagedTypeApiImpl, RawHandle, }, codec::{ DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, @@ -210,7 +210,6 @@ impl BigUint { Self::set_value(self.value.handle.clone(), value); } - #[inline] pub fn from_bytes_be(bytes: &[u8]) -> Self { let mb_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); M::managed_type_impl().mb_overwrite(mb_handle.clone(), bytes); @@ -221,7 +220,6 @@ impl BigUint { } } - #[inline] pub fn to_bytes_be(&self) -> BoxedBytes { let mb_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); M::managed_type_impl() @@ -229,44 +227,40 @@ impl BigUint { M::managed_type_impl().mb_to_boxed_bytes(mb_handle) } - #[inline] pub fn from_bytes_be_buffer(managed_buffer: &ManagedBuffer) -> Self { - let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl() - .mb_to_big_int_unsigned(managed_buffer.handle.clone(), handle.clone()); - unsafe { BigUint::from_handle(handle) } + unsafe { + let result = BigUint::new_uninit(); + M::managed_type_impl() + .mb_to_big_int_unsigned(managed_buffer.handle.clone(), result.get_handle()); + result + } } - #[inline] pub fn to_bytes_be_buffer(&self) -> ManagedBuffer { - let mb_handle: M::ManagedBufferHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl() - .mb_from_big_int_unsigned(self.value.handle.clone(), mb_handle.clone()); - unsafe { ManagedBuffer::from_handle(mb_handle) } + unsafe { + let result = ManagedBuffer::new_uninit(); + M::managed_type_impl().mb_from_big_int_unsigned(self.get_handle(), result.get_handle()); + result + } } } impl BigUint { - #[inline] - #[must_use] pub fn sqrt(&self) -> Self { - let api = M::managed_type_impl(); - let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - api.bi_sqrt(result_handle.clone(), self.value.handle.clone()); - unsafe { BigUint::from_handle(result_handle) } + unsafe { + let result = BigUint::new_uninit(); + M::managed_type_impl().bi_sqrt(result.get_handle(), self.get_handle()); + result + } } - #[must_use] pub fn pow(&self, exp: u32) -> Self { - let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); let big_int_temp_1 = BigUint::::make_temp(const_handles::BIG_INT_TEMPORARY_1, exp); - M::managed_type_impl().bi_pow( - result_handle.clone(), - self.value.handle.clone(), - big_int_temp_1, - ); - unsafe { BigUint::from_handle(result_handle) } + unsafe { + let result = BigUint::new_uninit(); + M::managed_type_impl().bi_pow(result.get_handle(), self.get_handle(), big_int_temp_1); + result + } } /// The whole part of the base-2 logarithm. @@ -275,7 +269,6 @@ impl BigUint { /// More specifically, the log2 floor is the position of the most significant bit minus one. /// /// Will return `None` for the number zero (the logarithm in this case would approach -inf). - #[inline] pub fn log2_floor(&self) -> Option { let api = M::managed_type_impl(); let result = api.bi_log2(self.value.handle.clone()); @@ -319,15 +312,7 @@ impl BigUint { impl Clone for BigUint { fn clone(&self) -> Self { - let api = M::managed_type_impl(); - let clone_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - api.bi_set_int64(clone_handle.clone(), 0); - api.bi_add( - clone_handle.clone(), - clone_handle.clone(), - self.value.handle.clone(), - ); - unsafe { BigUint::from_handle(clone_handle) } + unsafe { self.as_big_int().clone().into_big_uint_unchecked() } } } diff --git a/framework/base/src/types/managed/wrapped/big_uint_operators.rs b/framework/base/src/types/managed/wrapped/big_uint_operators.rs index a4becdcf10..5ca27f783e 100644 --- a/framework/base/src/types/managed/wrapped/big_uint_operators.rs +++ b/framework/base/src/types/managed/wrapped/big_uint_operators.rs @@ -1,5 +1,5 @@ use crate::{ - api::{const_handles, use_raw_handle, BigIntApiImpl, ManagedTypeApi, StaticVarApiImpl}, + api::{const_handles, BigIntApiImpl, ManagedTypeApi}, types::{BigUint, ManagedType}, }; use core::ops::{ @@ -14,9 +14,9 @@ macro_rules! binary_operator { fn $method(self, other: BigUint) -> BigUint { M::managed_type_impl().$api_func( - self.value.handle.clone(), - self.value.handle.clone(), - other.value.handle.clone(), + self.get_handle(), + self.get_handle(), + other.get_handle(), ); self } @@ -26,14 +26,15 @@ macro_rules! binary_operator { type Output = BigUint; fn $method(self, other: &BigUint) -> BigUint { - let result_handle: M::BigIntHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().$api_func( - result_handle.clone(), - self.value.handle.clone(), - other.value.handle.clone(), - ); - unsafe { BigUint::from_handle(result_handle) } + unsafe { + let result = BigUint::new_uninit(); + M::managed_type_impl().$api_func( + result.get_handle(), + self.get_handle(), + other.get_handle(), + ); + result + } } } @@ -42,9 +43,9 @@ macro_rules! binary_operator { fn $method(self, other: &BigUint) -> BigUint { M::managed_type_impl().$api_func( - self.value.handle.clone(), - self.value.handle.clone(), - other.value.handle.clone(), + self.get_handle(), + self.get_handle(), + other.get_handle(), ); self } @@ -56,8 +57,8 @@ macro_rules! binary_operator { fn $method(self, other: u32) -> BigUint { let big_int_temp_1 = Self::make_temp(const_handles::BIG_INT_TEMPORARY_1, other); M::managed_type_impl().$api_func( - self.value.handle.clone(), - self.value.handle.clone(), + self.get_handle(), + self.get_handle(), big_int_temp_1, ); self @@ -70,14 +71,15 @@ macro_rules! binary_operator { fn $method(self, other: u32) -> BigUint { let big_int_temp_1 = BigUint::::make_temp(const_handles::BIG_INT_TEMPORARY_1, other); - let result_handle: M::BigIntHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().$api_func( - result_handle.clone(), - self.value.handle.clone(), - big_int_temp_1, - ); - unsafe { BigUint::from_handle(result_handle) } + unsafe { + let result = BigUint::new_uninit(); + M::managed_type_impl().$api_func( + result.get_handle(), + self.get_handle(), + big_int_temp_1, + ); + result + } } } @@ -101,14 +103,15 @@ macro_rules! binary_operator { fn $method(self, other: u64) -> BigUint { let big_int_temp_1 = BigUint::::make_temp(const_handles::BIG_INT_TEMPORARY_1, other); - let result_handle: M::BigIntHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().$api_func( - result_handle.clone(), - self.value.handle.clone(), - big_int_temp_1, - ); - unsafe { BigUint::from_handle(result_handle) } + unsafe { + let result = BigUint::new_uninit(); + M::managed_type_impl().$api_func( + result.get_handle(), + self.get_handle(), + big_int_temp_1, + ); + result + } } } }; @@ -200,14 +203,11 @@ macro_rules! shift_traits { type Output = BigUint; fn $method(self, rhs: usize) -> BigUint { - let result_handle: M::BigIntHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().$api_func( - result_handle.clone(), - self.value.handle.clone(), - rhs, - ); - unsafe { BigUint::from_handle(result_handle) } + unsafe { + let result = BigUint::new_uninit(); + M::managed_type_impl().$api_func(result.get_handle(), self.get_handle(), rhs); + result + } } } }; From 812e9e55c835ee2f20ac75f7b44326729dbce829 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 11 Nov 2024 13:17:34 +0200 Subject: [PATCH 007/133] cleanup --- .../types/managed/wrapped/egld_or_esdt_token_identifier.rs | 6 ------ .../wrapped/managed_decimal/managed_decimal_logarithm.rs | 1 - 2 files changed, 7 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index 97bf533e69..6221188618 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -243,9 +243,6 @@ impl SCDisplay for EgldOrEsdtTokenIdentifier { let cast_handle = token_identifier.get_handle().cast_or_signal_error::(); let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; f.append_managed_buffer(&wrap_cast); - // f.append_managed_buffer(&ManagedBuffer::from_handle( - // token_identifier.get_handle().cast_or_signal_error::(), - // )); } else { f.append_bytes(Self::EGLD_REPRESENTATION); } @@ -260,9 +257,6 @@ impl SCLowerHex for EgldOrEsdtTokenIdentifier { let cast_handle = token_identifier.get_handle().cast_or_signal_error::(); let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; f.append_managed_buffer_lower_hex(&wrap_cast); - // f.append_managed_buffer_lower_hex(&ManagedBuffer::from_handle( - // token_identifier.get_handle().cast_or_signal_error::(), - // )); } else { f.append_bytes(EGLD_REPRESENTATION_HEX); } diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs index 698b2fbbee..43c4debbac 100644 --- a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs @@ -119,7 +119,6 @@ impl ManagedDecimalSigned { } let bu = unsafe { ManagedRef::wrap_handle(self.data.handle.clone()) }; - // let bu = BigUint::from_handle(self.data.handle.clone()); compute_log2(&bu, self.decimals.num_decimals()) } } From da9bea3451ffd5fa9434ab844c10b16d83776f5f Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 12 Nov 2024 09:40:11 +0200 Subject: [PATCH 008/133] ManagedOption refactor --- .../wrapped/egld_or_esdt_token_identifier.rs | 33 ++++++++++--------- .../types/managed/wrapped/managed_option.rs | 27 ++++++++------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index 6221188618..7a4611011d 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -25,7 +25,8 @@ use crate as multiversx_sc; // required by the ManagedVecItem derive /// /// It is, however more optimized than that. Its implementation is based on `ManagedOption`. /// -/// EGLD a special, invalid token identifier handle. This way we can fit it inside a single i32 in memory. +/// EGLD is indicated by a special, invalid token identifier handle. +/// This way we can fit it inside a single i32 in memory. #[repr(transparent)] #[derive(ManagedVecItem, Clone)] pub struct EgldOrEsdtTokenIdentifier { @@ -56,12 +57,12 @@ impl EgldOrEsdtTokenIdentifier { } } - pub fn from_opt_raw_handle(opt_handle: Option) -> Self { - match opt_handle { - Some(handle) => Self::esdt(unsafe { TokenIdentifier::from_handle(handle) }), - None => Self::egld(), - } - } + // pub fn from_opt_raw_handle(opt_handle: Option) -> Self { + // match opt_handle { + // Some(handle) => Self::esdt(unsafe { TokenIdentifier::from_handle(handle) }), + // None => Self::egld(), + // } + // } pub fn parse(data: ManagedBuffer) -> Self { if data == Self::EGLD_REPRESENTATION { @@ -268,13 +269,15 @@ where M: ManagedTypeApi, { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - if let Some(token_identifier) = self.data.as_option() { - let token_id_str = token_identifier.to_string(); - f.debug_tuple("EgldOrEsdtTokenIdentifier::Esdt") - .field(&token_id_str) - .finish() - } else { - f.write_str("EgldOrEsdtTokenIdentifier::Egld") - } + self.map_ref_or_else( + f, + |f| f.write_str("EgldOrEsdtTokenIdentifier::Egld"), + |f, token_identifier| { + let token_id_str = token_identifier.to_string(); + f.debug_tuple("EgldOrEsdtTokenIdentifier::Esdt") + .field(&token_id_str) + .finish() + }, + ) } } diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index e433913835..a432cde82f 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -41,7 +41,9 @@ where } pub fn some(value: T) -> Self { - Self::new_with_handle(value.get_handle()) + let handle = value.get_handle(); + core::mem::forget(value); + Self::new_with_handle(handle) } pub fn none() -> Self { @@ -143,7 +145,10 @@ where F: FnOnce(Context, &T) -> R, { if self.is_some() { - f(context, unsafe { &T::from_handle(self.handle.clone()) }) + let obj = unsafe { T::from_handle(self.handle.clone()) }; + let result = f(context, &obj); + core::mem::forget(obj); + result } else { default(context) } @@ -157,11 +162,7 @@ where { #[allow(clippy::redundant_clone)] // the clone is not redundant fn clone(&self) -> Self { - if self.is_some() { - Self::some(unsafe { T::from_handle(self.handle.clone()) }.clone()) - } else { - Self::none() - } + self.map_ref_or_else((), |()| Self::none(), |(), obj| Self::some(obj.clone())) } } @@ -328,12 +329,10 @@ where T: ManagedType + core::fmt::Debug, { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - if self.is_some() { - f.debug_tuple("ManagedOption::Some") - .field(unsafe { &T::from_handle(self.handle.clone()) }) - .finish() - } else { - f.write_str("ManagedOption::None") - } + self.map_ref_or_else( + f, + |f| f.write_str("ManagedOption::None"), + |f, obj| f.debug_tuple("ManagedOption::Some").field(obj).finish(), + ) } } From a97945c4680c6e504519afdf86807fe5eb990665 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 12 Nov 2024 09:41:38 +0200 Subject: [PATCH 009/133] cleanup --- .../types/managed/wrapped/egld_or_esdt_token_identifier.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index 7a4611011d..66dd7c9ec9 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -57,13 +57,6 @@ impl EgldOrEsdtTokenIdentifier { } } - // pub fn from_opt_raw_handle(opt_handle: Option) -> Self { - // match opt_handle { - // Some(handle) => Self::esdt(unsafe { TokenIdentifier::from_handle(handle) }), - // None => Self::egld(), - // } - // } - pub fn parse(data: ManagedBuffer) -> Self { if data == Self::EGLD_REPRESENTATION { Self::egld() From 9eac9fd1f9e300c25d39eb99684ece8678956552 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 15 Nov 2024 09:54:08 +0200 Subject: [PATCH 010/133] cargo fmt --- chain/vm/src/vm_hooks/vh_dispatcher.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/vm/src/vm_hooks/vh_dispatcher.rs b/chain/vm/src/vm_hooks/vh_dispatcher.rs index 46c5153819..1af9bfbb6a 100644 --- a/chain/vm/src/vm_hooks/vh_dispatcher.rs +++ b/chain/vm/src/vm_hooks/vh_dispatcher.rs @@ -1883,7 +1883,7 @@ impl VMHooks for VMHooksDispatcher { ) -> i32 { panic!("Unavailable: managed_multi_transfer_esdt_nft_execute_by_user") } - + fn managed_verify_secp256r1( &self, key_handle: i32, From f6d62d14df7a9fe2c9fb40c94aa8bd91027c2491 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 15 Nov 2024 09:56:07 +0200 Subject: [PATCH 011/133] using multiversx-chain-vm-executor v0.3.0 --- Cargo.lock | 5 +++-- chain/vm/Cargo.toml | 4 +--- framework/scenario/Cargo.toml | 4 +--- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95a73a2974..25a922d7a1 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -2428,8 +2428,9 @@ dependencies = [ [[package]] name = "multiversx-chain-vm-executor" -version = "0.2.0" -source = "git+https://github.com/multiversx/mx-vm-executor-rs?branch=rc/v1.7.next1#009e15459c023ec3b94fcebd826b381f7706229c" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51cce7ae386960fbf5e85afe40ca16d63f926f0620ed1a36b019212b28e17219" [[package]] name = "multiversx-price-aggregator-sc" diff --git a/chain/vm/Cargo.toml b/chain/vm/Cargo.toml index e412a709af..96d8b25926 100644 --- a/chain/vm/Cargo.toml +++ b/chain/vm/Cargo.toml @@ -39,6 +39,4 @@ version = "=0.11.0" path = "../core" [dependencies.multiversx-chain-vm-executor] -# version = "0.2.0" -git = "https://github.com/multiversx/mx-vm-executor-rs" -branch = "rc/v1.7.next1" +version = "0.3.0" diff --git a/framework/scenario/Cargo.toml b/framework/scenario/Cargo.toml index c019233953..a0982451ca 100644 --- a/framework/scenario/Cargo.toml +++ b/framework/scenario/Cargo.toml @@ -50,9 +50,7 @@ version = "0.23.0" path = "../../sdk/scenario-format" [dependencies.multiversx-chain-vm-executor] -# version = "0.2.0" -git = "https://github.com/multiversx/mx-vm-executor-rs" -branch = "rc/v1.7.next1" +version = "0.3.0" [dependencies.multiversx-chain-vm] version = "=0.11.0" From 57a580b741c5e09f4e2c415c198882f61c1419e8 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 15 Nov 2024 10:06:45 +0200 Subject: [PATCH 012/133] EI version comment --- framework/meta-lib/src/ei/ei_version.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/meta-lib/src/ei/ei_version.rs b/framework/meta-lib/src/ei/ei_version.rs index 6ba2444a6e..33fe86e254 100644 --- a/framework/meta-lib/src/ei/ei_version.rs +++ b/framework/meta-lib/src/ei/ei_version.rs @@ -29,7 +29,7 @@ pub enum EIVersion { #[default] V1_3, - /// Version to be released to mainnet in August 2024. + /// Hooks made available in the Spica release, November 12, 2024: https://multiversx.com/release/release-spica-v1-8-4-0 V1_4, /// Version planned for Q3 2024. From 28d5b919273c1669e203e5273a998094948a9b21 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 18 Nov 2024 22:28:14 +0200 Subject: [PATCH 013/133] ManagedType - forget_into_handle; ManagedOption fix --- framework/base/src/storage/storage_key.rs | 4 ++++ .../src/types/interaction/managed_arg_buffer.rs | 4 ++++ .../base/src/types/managed/basic/big_float.rs | 11 +++++++++++ framework/base/src/types/managed/basic/big_int.rs | 11 +++++++++++ .../base/src/types/managed/basic/elliptic_curve.rs | 11 +++++++++++ .../base/src/types/managed/basic/managed_buffer.rs | 11 +++++++++++ .../base/src/types/managed/basic/managed_map.rs | 11 +++++++++++ .../base/src/types/managed/managed_type_trait.rs | 5 +++++ .../managed/multi_value/multi_value_managed_vec.rs | 4 ++++ .../base/src/types/managed/wrapped/big_uint.rs | 4 ++++ .../src/types/managed/wrapped/managed_address.rs | 4 ++++ .../types/managed/wrapped/managed_byte_array.rs | 4 ++++ .../src/types/managed/wrapped/managed_option.rs | 14 +++++++------- .../base/src/types/managed/wrapped/managed_vec.rs | 4 ++++ .../src/types/managed/wrapped/token_identifier.rs | 4 ++++ 15 files changed, 99 insertions(+), 7 deletions(-) diff --git a/framework/base/src/storage/storage_key.rs b/framework/base/src/storage/storage_key.rs index b3a35643e1..74b4fa5171 100644 --- a/framework/base/src/storage/storage_key.rs +++ b/framework/base/src/storage/storage_key.rs @@ -32,6 +32,10 @@ where self.buffer.get_handle() } + unsafe fn forget_into_handle(self) -> Self::OwnHandle { + self.buffer.forget_into_handle() + } + fn transmute_from_handle_ref(handle_ref: &A::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/interaction/managed_arg_buffer.rs b/framework/base/src/types/interaction/managed_arg_buffer.rs index 009ad74e3a..e1b09441fc 100644 --- a/framework/base/src/types/interaction/managed_arg_buffer.rs +++ b/framework/base/src/types/interaction/managed_arg_buffer.rs @@ -43,6 +43,10 @@ where self.data.get_handle() } + unsafe fn forget_into_handle(self) -> Self::OwnHandle { + self.data.forget_into_handle() + } + fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/managed/basic/big_float.rs b/framework/base/src/types/managed/basic/big_float.rs index 634d76f67d..81c5c25c53 100644 --- a/framework/base/src/types/managed/basic/big_float.rs +++ b/framework/base/src/types/managed/basic/big_float.rs @@ -35,6 +35,17 @@ impl ManagedType for BigFloat { self.handle.clone() } + unsafe fn forget_into_handle(mut self) -> Self::OwnHandle { + unsafe { + let handle = core::mem::replace( + &mut self.handle, + core::mem::MaybeUninit::uninit().assume_init(), + ); + core::mem::forget(self); + handle + } + } + fn transmute_from_handle_ref(handle_ref: &M::BigFloatHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/managed/basic/big_int.rs b/framework/base/src/types/managed/basic/big_int.rs index 13c3b965af..e981f6a9ec 100644 --- a/framework/base/src/types/managed/basic/big_int.rs +++ b/framework/base/src/types/managed/basic/big_int.rs @@ -38,6 +38,17 @@ impl ManagedType for BigInt { self.handle.clone() } + unsafe fn forget_into_handle(mut self) -> Self::OwnHandle { + unsafe { + let handle = core::mem::replace( + &mut self.handle, + core::mem::MaybeUninit::uninit().assume_init(), + ); + core::mem::forget(self); + handle + } + } + fn transmute_from_handle_ref(handle_ref: &M::BigIntHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/managed/basic/elliptic_curve.rs b/framework/base/src/types/managed/basic/elliptic_curve.rs index 2cc7097a18..7252bd8b90 100644 --- a/framework/base/src/types/managed/basic/elliptic_curve.rs +++ b/framework/base/src/types/managed/basic/elliptic_curve.rs @@ -43,6 +43,17 @@ impl ManagedType for EllipticCurve { self.handle.clone() } + unsafe fn forget_into_handle(mut self) -> Self::OwnHandle { + unsafe { + let handle = core::mem::replace( + &mut self.handle, + core::mem::MaybeUninit::uninit().assume_init(), + ); + core::mem::forget(self); + handle + } + } + fn transmute_from_handle_ref(handle_ref: &M::EllipticCurveHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index d1e0b52f9e..17ee49a639 100644 --- a/framework/base/src/types/managed/basic/managed_buffer.rs +++ b/framework/base/src/types/managed/basic/managed_buffer.rs @@ -37,6 +37,17 @@ impl ManagedType for ManagedBuffer { self.handle.clone() } + unsafe fn forget_into_handle(mut self) -> Self::OwnHandle { + unsafe { + let handle = core::mem::replace( + &mut self.handle, + core::mem::MaybeUninit::uninit().assume_init(), + ); + core::mem::forget(self); + handle + } + } + fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/managed/basic/managed_map.rs b/framework/base/src/types/managed/basic/managed_map.rs index 139f93cf9c..e0d593a883 100644 --- a/framework/base/src/types/managed/basic/managed_map.rs +++ b/framework/base/src/types/managed/basic/managed_map.rs @@ -23,6 +23,17 @@ impl ManagedType for ManagedMap { self.handle.clone() } + unsafe fn forget_into_handle(mut self) -> Self::OwnHandle { + unsafe { + let handle = core::mem::replace( + &mut self.handle, + core::mem::MaybeUninit::uninit().assume_init(), + ); + core::mem::forget(self); + handle + } + } + fn transmute_from_handle_ref(handle_ref: &M::ManagedMapHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/managed/managed_type_trait.rs b/framework/base/src/types/managed/managed_type_trait.rs index ca9210d594..f7df30288f 100644 --- a/framework/base/src/types/managed/managed_type_trait.rs +++ b/framework/base/src/types/managed/managed_type_trait.rs @@ -11,6 +11,11 @@ pub trait ManagedType: Sized { fn get_handle(&self) -> Self::OwnHandle; + /// Forgets current object (does not run destructor), but extracts the handle. + /// + /// The handle remains an owned object, so the handle's destructor will run later, when dropped. + unsafe fn forget_into_handle(self) -> Self::OwnHandle; + #[doc(hidden)] unsafe fn from_raw_handle(handle: RawHandle) -> Self { Self::from_handle(Self::OwnHandle::new(handle)) diff --git a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs index 6ad36a25e8..feb99b561d 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs @@ -54,6 +54,10 @@ where self.0.get_handle() } + unsafe fn forget_into_handle(self) -> Self::OwnHandle { + self.0.forget_into_handle() + } + fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/managed/wrapped/big_uint.rs b/framework/base/src/types/managed/wrapped/big_uint.rs index 344842c2a3..8151110315 100644 --- a/framework/base/src/types/managed/wrapped/big_uint.rs +++ b/framework/base/src/types/managed/wrapped/big_uint.rs @@ -36,6 +36,10 @@ impl ManagedType for BigUint { self.value.handle.clone() } + unsafe fn forget_into_handle(self) -> Self::OwnHandle { + self.value.forget_into_handle() + } + fn transmute_from_handle_ref(handle_ref: &M::BigIntHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/managed/wrapped/managed_address.rs b/framework/base/src/types/managed/wrapped/managed_address.rs index a12200a039..ec3b338961 100644 --- a/framework/base/src/types/managed/wrapped/managed_address.rs +++ b/framework/base/src/types/managed/wrapped/managed_address.rs @@ -167,6 +167,10 @@ where self.bytes.get_handle() } + unsafe fn forget_into_handle(self) -> Self::OwnHandle { + self.bytes.forget_into_handle() + } + fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/managed/wrapped/managed_byte_array.rs b/framework/base/src/types/managed/wrapped/managed_byte_array.rs index 5ef3e661b7..76f292e7e8 100644 --- a/framework/base/src/types/managed/wrapped/managed_byte_array.rs +++ b/framework/base/src/types/managed/wrapped/managed_byte_array.rs @@ -45,6 +45,10 @@ where self.buffer.get_handle() } + unsafe fn forget_into_handle(self) -> Self::OwnHandle { + self.buffer.forget_into_handle() + } + fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index a432cde82f..767592363d 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -41,9 +41,7 @@ where } pub fn some(value: T) -> Self { - let handle = value.get_handle(); - core::mem::forget(value); - Self::new_with_handle(handle) + unsafe { Self::new_with_handle(value.forget_into_handle()) } } pub fn none() -> Self { @@ -145,10 +143,12 @@ where F: FnOnce(Context, &T) -> R, { if self.is_some() { - let obj = unsafe { T::from_handle(self.handle.clone()) }; - let result = f(context, &obj); - core::mem::forget(obj); - result + unsafe { + let obj = T::from_handle(self.handle.clone()); + let result = f(context, &obj); + let _ = obj.forget_into_handle(); + result + } } else { default(context) } diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 582054e6ec..d3212e4d03 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -56,6 +56,10 @@ where self.buffer.get_handle() } + unsafe fn forget_into_handle(self) -> Self::OwnHandle { + self.buffer.forget_into_handle() + } + fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } diff --git a/framework/base/src/types/managed/wrapped/token_identifier.rs b/framework/base/src/types/managed/wrapped/token_identifier.rs index 10c92475a3..39fd17f5e1 100644 --- a/framework/base/src/types/managed/wrapped/token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/token_identifier.rs @@ -36,6 +36,10 @@ impl ManagedType for TokenIdentifier { self.buffer.get_handle() } + unsafe fn forget_into_handle(self) -> Self::OwnHandle { + self.buffer.forget_into_handle() + } + fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { unsafe { core::mem::transmute(handle_ref) } } From cc250e1c81b968f4f3ceb15b1b422a1f5f80e72f Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 18 Nov 2024 22:36:13 +0200 Subject: [PATCH 014/133] ManagedType - forget_into_handle in to ManagedVecItem impl for managed types --- .../base/src/types/managed/wrapped/managed_vec_item.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 8e88624d75..a883d991e3 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -203,7 +203,8 @@ macro_rules! impl_managed_type { } fn into_byte_writer R>(self, writer: Writer) -> R { - <$ty as ManagedType>::OwnHandle::into_byte_writer(self.get_handle(), writer) + let handle = unsafe { self.forget_into_handle() }; + <$ty as ManagedType>::OwnHandle::into_byte_writer(handle, writer) } } }; @@ -266,7 +267,8 @@ where } fn into_byte_writer R>(self, writer: Writer) -> R { - ::into_byte_writer(self.get_handle(), writer) + let handle = unsafe { self.forget_into_handle() }; + ::into_byte_writer(handle, writer) } } From 835d656cf1669f5359cf63fc9ec6afc6d91d32ad Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 18 Nov 2024 22:45:45 +0200 Subject: [PATCH 015/133] cargo clippy & fmt --- framework/base/src/types/managed/basic/big_float.rs | 7 ++----- framework/base/src/types/managed/basic/big_int.rs | 7 ++----- .../base/src/types/managed/basic/elliptic_curve.rs | 7 ++----- .../base/src/types/managed/basic/managed_buffer.rs | 7 ++----- .../base/src/types/managed/basic/managed_map.rs | 7 ++----- .../base/src/types/managed/managed_type_trait.rs | 12 +++++++++++- 6 files changed, 21 insertions(+), 26 deletions(-) diff --git a/framework/base/src/types/managed/basic/big_float.rs b/framework/base/src/types/managed/basic/big_float.rs index 81c5c25c53..9306769130 100644 --- a/framework/base/src/types/managed/basic/big_float.rs +++ b/framework/base/src/types/managed/basic/big_float.rs @@ -35,12 +35,9 @@ impl ManagedType for BigFloat { self.handle.clone() } - unsafe fn forget_into_handle(mut self) -> Self::OwnHandle { + unsafe fn forget_into_handle(self) -> Self::OwnHandle { unsafe { - let handle = core::mem::replace( - &mut self.handle, - core::mem::MaybeUninit::uninit().assume_init(), - ); + let handle = core::ptr::read(&self.handle); core::mem::forget(self); handle } diff --git a/framework/base/src/types/managed/basic/big_int.rs b/framework/base/src/types/managed/basic/big_int.rs index e981f6a9ec..464bc4150c 100644 --- a/framework/base/src/types/managed/basic/big_int.rs +++ b/framework/base/src/types/managed/basic/big_int.rs @@ -38,12 +38,9 @@ impl ManagedType for BigInt { self.handle.clone() } - unsafe fn forget_into_handle(mut self) -> Self::OwnHandle { + unsafe fn forget_into_handle(self) -> Self::OwnHandle { unsafe { - let handle = core::mem::replace( - &mut self.handle, - core::mem::MaybeUninit::uninit().assume_init(), - ); + let handle = core::ptr::read(&self.handle); core::mem::forget(self); handle } diff --git a/framework/base/src/types/managed/basic/elliptic_curve.rs b/framework/base/src/types/managed/basic/elliptic_curve.rs index 7252bd8b90..9b86dba5d1 100644 --- a/framework/base/src/types/managed/basic/elliptic_curve.rs +++ b/framework/base/src/types/managed/basic/elliptic_curve.rs @@ -43,12 +43,9 @@ impl ManagedType for EllipticCurve { self.handle.clone() } - unsafe fn forget_into_handle(mut self) -> Self::OwnHandle { + unsafe fn forget_into_handle(self) -> Self::OwnHandle { unsafe { - let handle = core::mem::replace( - &mut self.handle, - core::mem::MaybeUninit::uninit().assume_init(), - ); + let handle = core::ptr::read(&self.handle); core::mem::forget(self); handle } diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index 17ee49a639..cafa32a4d2 100644 --- a/framework/base/src/types/managed/basic/managed_buffer.rs +++ b/framework/base/src/types/managed/basic/managed_buffer.rs @@ -37,12 +37,9 @@ impl ManagedType for ManagedBuffer { self.handle.clone() } - unsafe fn forget_into_handle(mut self) -> Self::OwnHandle { + unsafe fn forget_into_handle(self) -> Self::OwnHandle { unsafe { - let handle = core::mem::replace( - &mut self.handle, - core::mem::MaybeUninit::uninit().assume_init(), - ); + let handle = core::ptr::read(&self.handle); core::mem::forget(self); handle } diff --git a/framework/base/src/types/managed/basic/managed_map.rs b/framework/base/src/types/managed/basic/managed_map.rs index e0d593a883..2fce9deb76 100644 --- a/framework/base/src/types/managed/basic/managed_map.rs +++ b/framework/base/src/types/managed/basic/managed_map.rs @@ -23,12 +23,9 @@ impl ManagedType for ManagedMap { self.handle.clone() } - unsafe fn forget_into_handle(mut self) -> Self::OwnHandle { + unsafe fn forget_into_handle(self) -> Self::OwnHandle { unsafe { - let handle = core::mem::replace( - &mut self.handle, - core::mem::MaybeUninit::uninit().assume_init(), - ); + let handle = core::ptr::read(&self.handle); core::mem::forget(self); handle } diff --git a/framework/base/src/types/managed/managed_type_trait.rs b/framework/base/src/types/managed/managed_type_trait.rs index f7df30288f..8b30fb8400 100644 --- a/framework/base/src/types/managed/managed_type_trait.rs +++ b/framework/base/src/types/managed/managed_type_trait.rs @@ -12,8 +12,18 @@ pub trait ManagedType: Sized { fn get_handle(&self) -> Self::OwnHandle; /// Forgets current object (does not run destructor), but extracts the handle. - /// + /// /// The handle remains an owned object, so the handle's destructor will run later, when dropped. + /// + /// ## Safety + /// + /// Destructures the object, without running a constructor. + /// + /// To avoid a memory leak, it is necessary for the object to be later + /// reconstructed from handle and its destructor run. + /// + /// It is designed to be used ManagedVec and ManagedOption, + /// where items are dropped later, together with their container. unsafe fn forget_into_handle(self) -> Self::OwnHandle; #[doc(hidden)] From 04e59ef11fd4ab1991bab0dfb0484e094b1ebce8 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Wed, 20 Nov 2024 17:10:15 +0100 Subject: [PATCH 016/133] set state initial implementation for chain simulator, test in adder --- .../adder/interactor/src/basic_interactor.rs | 2 +- .../tests/basic_interactor_cs_test.rs | 28 ++++++ .../interactor/interactor_chain_simulator.rs | 13 ++- .../src/interactor/interactor_sender.rs | 19 +++- sdk/core/src/gateway.rs | 3 + .../gateway_chain_simulator_set_state.rs | 94 +++++++++++++++++++ 6 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 sdk/core/src/gateway/gateway_chain_simulator_set_state.rs diff --git a/contracts/examples/adder/interactor/src/basic_interactor.rs b/contracts/examples/adder/interactor/src/basic_interactor.rs index 63d71de11a..64dff9673e 100644 --- a/contracts/examples/adder/interactor/src/basic_interactor.rs +++ b/contracts/examples/adder/interactor/src/basic_interactor.rs @@ -57,7 +57,7 @@ impl AdderInteract { let adder_owner_address = interactor.register_wallet(test_wallets::heidi()).await; let wallet_address = interactor.register_wallet(test_wallets::ivan()).await; - interactor.generate_blocks_until_epoch(1).await.unwrap(); + let _ = interactor.generate_blocks(30u64).await; AdderInteract { interactor, diff --git a/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs b/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs index 1f07ee4c87..d6b98b73e5 100644 --- a/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs +++ b/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs @@ -1,4 +1,5 @@ use basic_interactor::{AdderInteract, Config}; +use multiversx_sc_snippets::{sdk::gateway::SetStateAccount, test_wallets}; #[tokio::test] #[cfg_attr(not(feature = "chain-simulator-tests"), ignore)] @@ -33,3 +34,30 @@ async fn simulator_upgrade_test() { let sum = basic_interact.get_sum().await; assert_eq!(sum, 7u32.into()); } + +#[tokio::test] +#[cfg_attr(not(feature = "chain-simulator-tests"), ignore)] +async fn set_state_cs_test() { + let account_address = test_wallets::mike(); + + let real_chain_interact = AdderInteract::new(Config::load_config()).await; + let simulator_interact = AdderInteract::new(Config::chain_simulator_config()).await; + + let account = real_chain_interact + .interactor + .get_account(&account_address.to_address()) + .await; + let keys = real_chain_interact + .interactor + .get_account_storage(&account_address.to_address()) + .await; + + let set_state_account = SetStateAccount::from(account).with_keys(keys); + let vec_state = vec![set_state_account]; + + let set_state_response = simulator_interact.interactor.set_state(vec_state).await; + + let _ = simulator_interact.interactor.generate_blocks(2u64).await; + + assert!(set_state_response.is_ok()); +} diff --git a/framework/snippets/src/interactor/interactor_chain_simulator.rs b/framework/snippets/src/interactor/interactor_chain_simulator.rs index 44943fe243..24dfa5390e 100644 --- a/framework/snippets/src/interactor/interactor_chain_simulator.rs +++ b/framework/snippets/src/interactor/interactor_chain_simulator.rs @@ -1,7 +1,8 @@ use anyhow::Error; use multiversx_sc_scenario::imports::Address; use multiversx_sdk::gateway::{ - ChainSimulatorGenerateBlocksRequest, ChainSimulatorSendFundsRequest, GatewayAsyncService, + ChainSimulatorGenerateBlocksRequest, ChainSimulatorSendFundsRequest, + ChainSimulatorSetStateRequest, GatewayAsyncService, SetStateAccount, }; use crate::InteractorBase; @@ -53,4 +54,14 @@ where )) .await } + + pub async fn set_state(&self, account: Vec) -> Result { + if !self.use_chain_simulator { + return Ok(String::from("no-simulator")); + } + + self.proxy + .request(ChainSimulatorSetStateRequest::for_account(account)) + .await + } } diff --git a/framework/snippets/src/interactor/interactor_sender.rs b/framework/snippets/src/interactor/interactor_sender.rs index e3877dec0a..4ba0efa162 100644 --- a/framework/snippets/src/interactor/interactor_sender.rs +++ b/framework/snippets/src/interactor/interactor_sender.rs @@ -1,7 +1,10 @@ +use std::collections::HashMap; + use crate::sdk::{data::transaction::Transaction, wallet::Wallet}; use log::debug; use multiversx_sc_scenario::multiversx_sc::types::Address; -use multiversx_sdk::gateway::{GatewayAsyncService, GetAccountRequest}; +use multiversx_sdk::data::account::Account; +use multiversx_sdk::gateway::{GatewayAsyncService, GetAccountRequest, GetAccountStorageRequest}; use crate::InteractorBase; @@ -25,6 +28,20 @@ where account.nonce } + pub async fn get_account(&self, address: &Address) -> Account { + self.proxy + .request(GetAccountRequest::new(address)) + .await + .expect("failed to retrieve account") + } + + pub async fn get_account_storage(&self, address: &Address) -> HashMap { + self.proxy + .request(GetAccountStorageRequest::new(address)) + .await + .expect("failed to retrieve account") + } + pub(crate) async fn set_nonce_and_sign_tx( &mut self, sender_address: &Address, diff --git a/sdk/core/src/gateway.rs b/sdk/core/src/gateway.rs index 1512717a85..f3e08a4af2 100644 --- a/sdk/core/src/gateway.rs +++ b/sdk/core/src/gateway.rs @@ -5,6 +5,7 @@ mod gateway_account_storage; mod gateway_block; mod gateway_chain_simulator_blocks; mod gateway_chain_simulator_send_funds; +mod gateway_chain_simulator_set_state; mod gateway_network_config; mod gateway_network_economics; mod gateway_network_status; @@ -23,6 +24,7 @@ pub use gateway_account_storage::GetAccountStorageRequest; pub use gateway_block::GetHyperBlockRequest; pub use gateway_chain_simulator_blocks::ChainSimulatorGenerateBlocksRequest; pub use gateway_chain_simulator_send_funds::ChainSimulatorSendFundsRequest; +pub use gateway_chain_simulator_set_state::{ChainSimulatorSetStateRequest, SetStateAccount}; pub use gateway_network_config::NetworkConfigRequest; pub use gateway_network_economics::NetworkEconimicsRequest; pub use gateway_network_status::NetworkStatusRequest; @@ -61,6 +63,7 @@ const GENERATE_BLOCKS_UNTIL_TX_PROCESSED_ENDPOINT: &str = "simulator/generate-blocks-until-transaction-processed"; const GENERATE_BLOCKS_UNTIL_EPOCH_REACHED_ENDPOINT: &str = "simulator/generate-blocks-until-epoch-reached"; +const SET_STATE_ENDPOINT: &str = "simulator/set-state"; pub enum GatewayRequestType { Get, diff --git a/sdk/core/src/gateway/gateway_chain_simulator_set_state.rs b/sdk/core/src/gateway/gateway_chain_simulator_set_state.rs new file mode 100644 index 0000000000..33644e72a3 --- /dev/null +++ b/sdk/core/src/gateway/gateway_chain_simulator_set_state.rs @@ -0,0 +1,94 @@ +use anyhow::anyhow; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +use crate::data::account::Account; + +use super::{GatewayRequest, GatewayRequestType, SET_STATE_ENDPOINT}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SetStateResponse { + pub data: serde_json::Value, + pub error: String, + pub code: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct SetStateAccount { + pub address: String, + pub nonce: u64, + pub balance: String, + pub keys: HashMap, + pub code: String, + #[serde(default)] + pub code_hash: String, + #[serde(default)] + pub root_hash: String, + #[serde(default)] + pub code_metadata: String, + #[serde(default)] + pub owner_address: String, + #[serde(default)] + pub developer_reward: String, +} + +impl From for SetStateAccount { + fn from(value: Account) -> Self { + Self { + address: value.address.to_bech32_string().unwrap_or_default(), + nonce: value.nonce, + balance: value.balance.to_string(), + keys: HashMap::new(), + code: value.code, + code_hash: value.code_hash.unwrap_or_default(), + root_hash: value.root_hash.unwrap_or_default(), + code_metadata: value.code_metadata.unwrap_or_default(), + owner_address: value.owner_address.unwrap_or_default(), + developer_reward: value.developer_reward.unwrap_or_default(), + } + } +} + +impl SetStateAccount { + pub fn with_keys(mut self, keys: HashMap) -> Self { + self.keys = keys; + + self + } +} + +/// Sets state for a list of accounts using the chain simulator API. +pub struct ChainSimulatorSetStateRequest { + pub account: Vec, +} + +impl ChainSimulatorSetStateRequest { + pub fn for_account(account: Vec) -> Self { + Self { account } + } +} + +impl GatewayRequest for ChainSimulatorSetStateRequest { + type Payload = Vec; + type DecodedJson = SetStateResponse; + type Result = String; + + fn get_payload(&self) -> Option<&Self::Payload> { + Some(&self.account) + } + + fn request_type(&self) -> GatewayRequestType { + GatewayRequestType::Post + } + + fn get_endpoint(&self) -> String { + SET_STATE_ENDPOINT.to_owned() + } + + fn process_json(&self, decoded: Self::DecodedJson) -> anyhow::Result { + match decoded.code.as_str() { + "successful" => Ok(decoded.code), + _ => Err(anyhow!("{}", decoded.error)), + } + } +} From 445d7bcd06f06f6869687b4b52488d335bd5cd31 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Thu, 21 Nov 2024 13:42:04 +0100 Subject: [PATCH 017/133] typos --- .../snippets/src/interactor/interactor_chain_simulator.rs | 4 ++-- sdk/core/src/gateway/gateway_chain_simulator_set_state.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/framework/snippets/src/interactor/interactor_chain_simulator.rs b/framework/snippets/src/interactor/interactor_chain_simulator.rs index 24dfa5390e..17ca51f3a7 100644 --- a/framework/snippets/src/interactor/interactor_chain_simulator.rs +++ b/framework/snippets/src/interactor/interactor_chain_simulator.rs @@ -55,13 +55,13 @@ where .await } - pub async fn set_state(&self, account: Vec) -> Result { + pub async fn set_state(&self, accounts: Vec) -> Result { if !self.use_chain_simulator { return Ok(String::from("no-simulator")); } self.proxy - .request(ChainSimulatorSetStateRequest::for_account(account)) + .request(ChainSimulatorSetStateRequest::for_accounts(accounts)) .await } } diff --git a/sdk/core/src/gateway/gateway_chain_simulator_set_state.rs b/sdk/core/src/gateway/gateway_chain_simulator_set_state.rs index 33644e72a3..77b46d4422 100644 --- a/sdk/core/src/gateway/gateway_chain_simulator_set_state.rs +++ b/sdk/core/src/gateway/gateway_chain_simulator_set_state.rs @@ -59,12 +59,12 @@ impl SetStateAccount { /// Sets state for a list of accounts using the chain simulator API. pub struct ChainSimulatorSetStateRequest { - pub account: Vec, + pub accounts: Vec, } impl ChainSimulatorSetStateRequest { - pub fn for_account(account: Vec) -> Self { - Self { account } + pub fn for_accounts(accounts: Vec) -> Self { + Self { accounts } } } @@ -74,7 +74,7 @@ impl GatewayRequest for ChainSimulatorSetStateRequest { type Result = String; fn get_payload(&self) -> Option<&Self::Payload> { - Some(&self.account) + Some(&self.accounts) } fn request_type(&self) -> GatewayRequestType { From d829a3d8be070c64a43c3ebf70ec50c3ca2fd733 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 25 Nov 2024 15:15:55 +0200 Subject: [PATCH 018/133] ManagedVecItem payload refactor - several attempts --- .../esdt_token_payment_multi_value.rs | 5 +- .../managed/wrapped/esdt_token_payment.rs | 4 + .../types/managed/wrapped/managed_option.rs | 4 + .../types/managed/wrapped/managed_vec_item.rs | 56 ++++++- .../wrapped/managed_vec_item_nested_tuple.rs | 63 +++++++ .../wrapped/managed_vec_item_payload.rs | 155 +++++++++++++++++- .../base/src/types/managed/wrapped/mod.rs | 2 +- .../derive/src/managed_vec_item_derive.rs | 8 + .../src/api/impl_vh/debug_handle_vh.rs | 4 + 9 files changed, 295 insertions(+), 6 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 1ebc5d5fe7..4eb6fc60d8 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -44,11 +44,14 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { const SKIPS_RESERIALIZATION: bool = EsdtTokenPayment::::SKIPS_RESERIALIZATION; type Ref<'a> = Self; - #[inline] fn from_byte_reader(reader: Reader) -> Self { EsdtTokenPayment::from_byte_reader(reader).into() } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + EsdtTokenPayment::read_from_payload(payload).into() + } + #[inline] unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index cf2ccf0ceb..a92a9cbe16 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -205,6 +205,10 @@ impl ManagedVecItem for EsdtTokenPayment { } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + todo!() + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index 767592363d..ae77c6bc92 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -208,6 +208,10 @@ where Self::new_with_handle(handle) } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + Self::new_with_handle(use_raw_handle(i32::read_from_payload(payload))) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index a883d991e3..8c06da18c3 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -3,14 +3,14 @@ use core::borrow::Borrow; use multiversx_chain_core::types::{EsdtLocalRole, EsdtTokenType}; use crate::{ - api::ManagedTypeApi, + api::{use_raw_handle, ManagedTypeApi}, types::{ BigInt, BigUint, EllipticCurve, ManagedAddress, ManagedBuffer, ManagedByteArray, ManagedRef, ManagedType, ManagedVec, TokenIdentifier, }, }; -use super::{ManagedVecItemNestedTuple, ManagedVecItemPayload, ManagedVecItemPayloadBuffer}; +use super::{ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, ManagedVecItemPayload, ManagedVecItemPayloadBuffer}; /// Types that implement this trait can be items inside a `ManagedVec`. /// All these types need a payload, i.e a representation that gets stored @@ -44,6 +44,8 @@ pub trait ManagedVecItem: 'static { /// Parses given bytes as a an owned object. fn from_byte_reader(reader: Reader) -> Self; + fn read_from_payload(payload: &Self::PAYLOAD) -> Self; + /// Parses given bytes as a representation of the object, either owned, or a reference. /// /// # Safety @@ -71,11 +73,17 @@ macro_rules! impl_int { type PAYLOAD = ManagedVecItemPayloadBuffer<$payload_size>; const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; + fn from_byte_reader(mut reader: Reader) -> Self { let mut arr: [u8; $payload_size] = [0u8; $payload_size]; reader(&mut arr[..]); $ty::from_be_bytes(arr) } + + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + $ty::from_be_bytes(payload.buffer) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -107,6 +115,10 @@ impl ManagedVecItem for usize { u32::from_be_bytes(arr) as usize } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + u32::read_from_payload(payload) as usize + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -128,6 +140,10 @@ impl ManagedVecItem for bool { u8::from_byte_reader(reader) > 0 } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + u8::read_from_payload(payload) > 0 + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -164,6 +180,17 @@ where } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + // let (p1, (p2, ())) = <(u8, (T, ()))>::split_all(payload); + + // let disc = u8::read_from_payload(p1); + // let x = split_payload(payload); + // Self::PAYLOAD::spli + todo!() + // let (disc_payload, t_payload) = payload.split::<1>(); + // let x = payload; + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -195,6 +222,11 @@ macro_rules! impl_managed_type { unsafe { $ty::from_handle(handle) } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + let handle = use_raw_handle(i32::read_from_payload(payload)); + unsafe { Self::from_handle(handle) } + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -230,6 +262,11 @@ where unsafe { Self::from_handle(handle) } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + let handle = use_raw_handle(i32::read_from_payload(payload)); + unsafe { Self::from_handle(handle) } + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -259,6 +296,11 @@ where unsafe { Self::from_handle(handle) } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + let handle = use_raw_handle(i32::read_from_payload(payload)); + unsafe { Self::from_handle(handle) } + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -283,6 +325,10 @@ impl ManagedVecItem for EsdtTokenType { arr[0].into() } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + u8::read_from_payload(payload).into() + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -295,7 +341,7 @@ impl ManagedVecItem for EsdtTokenType { } impl ManagedVecItem for EsdtLocalRole { - type PAYLOAD = ManagedVecItemPayloadBuffer<1>; + type PAYLOAD = ManagedVecItemPayloadBuffer<2>; const SKIPS_RESERIALIZATION: bool = false; // TODO: might be ok to be true, but needs testing type Ref<'a> = Self; @@ -303,6 +349,10 @@ impl ManagedVecItem for EsdtLocalRole { u16::from_byte_reader(reader).into() } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + u16::read_from_payload(payload).into() + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs index 3a25bf4993..45e6a8d820 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs @@ -5,11 +5,35 @@ use super::{ /// Syntactic sugar, that allows us to more easily represent composite payloads as nested tuples. pub trait ManagedVecItemNestedTuple { type PAYLOAD: ManagedVecItemPayload; + type Split1: ManagedVecItemPayload; + type Split2: ManagedVecItemPayload; + + fn split_payload(payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2); +} + +pub trait ManagedVecItemNestedTupleSplit<'a>: ManagedVecItemNestedTuple { + type S; + + fn split_all(payload: &'a Self::PAYLOAD) -> Self::S; } /// End of the list. impl ManagedVecItemNestedTuple for () { type PAYLOAD = ManagedVecItemEmptyPayload; + type Split1 = ManagedVecItemEmptyPayload; + type Split2 = ManagedVecItemEmptyPayload; + + fn split_payload(_payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2) { + (&ManagedVecItemEmptyPayload, &ManagedVecItemEmptyPayload) + } +} + +impl<'a> ManagedVecItemNestedTupleSplit<'a> for () { + type S = (); + + fn split_all(_payload: &'a Self::PAYLOAD) -> Self::S { + () + } } impl ManagedVecItemNestedTuple for (Head, Tail) @@ -19,8 +43,47 @@ where Head::PAYLOAD: ManagedVecItemPayloadAdd, { type PAYLOAD = >::Output; + type Split1 = ::PAYLOAD; + type Split2 = ::PAYLOAD; + + fn split_payload(payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2) { + Head::PAYLOAD::split_from_add(payload) + } +} + +impl<'a, Head, Tail> ManagedVecItemNestedTupleSplit<'a> for (Head, Tail) +where + Head: ManagedVecItem, + Tail: ManagedVecItemNestedTupleSplit<'a>, + Head::PAYLOAD: ManagedVecItemPayloadAdd, + Tail::PAYLOAD: 'a, +{ + type S = (&'a Head::PAYLOAD, Tail::S); + + fn split_all(payload: &'a Self::PAYLOAD) -> Self::S { + let (hp, tp) = Head::PAYLOAD::split_from_add(payload); + (hp, Tail::split_all(tp)) + } } +// pub fn split_payload( +// payload: &<(Head, Tail) as ManagedVecItemNestedTuple>::PAYLOAD, +// ) -> (&Head::PAYLOAD, &Tail::PAYLOAD) +// where +// Head: ManagedVecItem, +// Tail: ManagedVecItemNestedTuple, +// Head::PAYLOAD: ManagedVecItemPayloadAdd, +// // (Head, Tail): ManagedVecItemNestedTuple, +// { +// >::split_from_add(payload) +// // <(Head, Tail) as ManagedVecItemNestedTuple>::PAYLOAD as +// // unsafe { +// // let ptr1 = payload.buffer.as_ptr(); +// // let ptr2 = ptr1.offset($dec1 as isize); +// // (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) +// // } +// } + #[cfg(test)] pub mod tests { use super::*; diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index 07adc31a08..4fcc20d9d3 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -1,3 +1,5 @@ +use core::marker::PhantomData; + /// Describes the binary represetnation of a ManagedVecItem. /// /// It is always an array that can be allocated directly on stack. @@ -35,8 +37,9 @@ impl ManagedVecItemPayload for ManagedVecItemEmptyPayload { } /// The main ManagedVecItemPayload implementation. Uses an array in its implementation. +#[repr(transparent)] pub struct ManagedVecItemPayloadBuffer { - buffer: [u8; N], + pub buffer: [u8; N], } impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { @@ -57,6 +60,83 @@ impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { } } +#[repr(transparent)] +pub struct ManagedVecItemPayloadConcat +where + P1: ManagedVecItemPayload, + P2: ManagedVecItemPayload, + P1: ManagedVecItemPayloadAdd, +{ + _phantom_1: PhantomData, + _phantom_2: PhantomData, + buffer: >::Output, +} + +impl ManagedVecItemPayload for ManagedVecItemPayloadConcat +where + P1: ManagedVecItemPayload, + P2: ManagedVecItemPayload, + P1: ManagedVecItemPayloadAdd, +{ + fn new_buffer() -> Self { + ManagedVecItemPayloadConcat { + _phantom_1: PhantomData, + _phantom_2: PhantomData, + buffer: ManagedVecItemPayload::new_buffer(), + } + } + + fn payload_size() -> usize { + >::Output::payload_size() + } + + fn payload_slice(&self) -> &[u8] { + self.buffer.payload_slice() + } + + fn payload_slice_mut(&mut self) -> &mut [u8] { + self.buffer.payload_slice_mut() + } +} + +impl ManagedVecItemPayloadConcat +where + P1: ManagedVecItemPayload, + P2: ManagedVecItemPayload, + P1: ManagedVecItemPayloadAdd, +{ +} + +impl ManagedVecItemPayloadAdd> for P0 +where + P0: ManagedVecItemPayload, + P1: ManagedVecItemPayload, + P2: ManagedVecItemPayload, + P1: ManagedVecItemPayloadAdd, + P0: ManagedVecItemPayloadAdd<>::Output>, +{ + type Output = ManagedVecItemPayloadConcat>; + + fn split_from_add(payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { + todo!() + } + + + + // fn split_from_add( + // payload: &ManagedVecItemPayloadBuffer<$result_add>, + // ) -> ( + // &ManagedVecItemPayloadBuffer<$dec1>, + // &ManagedVecItemPayloadBuffer<$dec2>, + // ) { + // unsafe { + // let ptr1 = payload.buffer.as_ptr(); + // let ptr2 = ptr1.offset($dec1 as isize); + // (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) + // } + // } +} + /// Describes concatantion of smaller payloads into a larger one. /// /// There is no runtime implementation, just a type-level addition. @@ -67,12 +147,39 @@ where Rhs: ManagedVecItemPayload, { type Output: ManagedVecItemPayload; + + fn split_from_add(payload: &Self::Output) -> (&Self, &Rhs); } impl ManagedVecItemPayloadAdd for ManagedVecItemPayloadBuffer { type Output = Self; + + fn split_from_add(payload: &Self::Output) -> (&Self, &ManagedVecItemEmptyPayload) { + (payload, &ManagedVecItemEmptyPayload) + } +} + +pub trait ManagedVecItemPayloadSplit: ManagedVecItemPayload { + type P1: ManagedVecItemPayload; + type P2: ManagedVecItemPayload; + + fn split_impl(&self) -> (&Self::P1, &Self::P2); +} + +impl ManagedVecItemPayloadBuffer { + pub fn split_me( + &self, + ) -> ( + &>::P1, + &>::P2, + ) + where + Self: ManagedVecItemPayloadSplit, + { + ManagedVecItemPayloadSplit::::split_impl(self) + } } /// Replaces a const generic expression. @@ -84,10 +191,56 @@ macro_rules! payload_add { for ManagedVecItemPayloadBuffer<$dec1> { type Output = ManagedVecItemPayloadBuffer<$result_add>; + + fn split_from_add( + payload: &ManagedVecItemPayloadBuffer<$result_add>, + ) -> ( + &ManagedVecItemPayloadBuffer<$dec1>, + &ManagedVecItemPayloadBuffer<$dec2>, + ) { + unsafe { + let ptr1 = payload.buffer.as_ptr(); + let ptr2 = ptr1.offset($dec1 as isize); + (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) + } + } + } + + impl ManagedVecItemPayloadSplit<$dec1> for ManagedVecItemPayloadBuffer<$result_add> { + type P1 = ManagedVecItemPayloadBuffer<$dec1>; + type P2 = ManagedVecItemPayloadBuffer<$dec2>; + + fn split_impl( + &self, + ) -> ( + &ManagedVecItemPayloadBuffer<$dec1>, + &ManagedVecItemPayloadBuffer<$dec2>, + ) { + unsafe { + let ptr1 = self.buffer.as_ptr(); + let ptr2 = ptr1.offset($dec1 as isize); + (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) + } + } } }; } +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn payload_split() { + let payload = ManagedVecItemPayloadBuffer { + buffer: [1, 2, 3, 4, 5], + }; + let (p1, p2) = payload.split_me::<3>(); + assert_eq!(p1.buffer, [1, 2, 3]); + assert_eq!(p2.buffer, [4, 5]); + } +} + payload_add!(1usize, 1usize, 2usize); payload_add!(1usize, 2usize, 3usize); payload_add!(1usize, 3usize, 4usize); diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped/mod.rs index 37849e0b6c..f4db4e5212 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -47,7 +47,7 @@ pub use managed_ref::ManagedRef; pub use managed_ref_mut::ManagedRefMut; pub use managed_vec::ManagedVec; pub use managed_vec_item::ManagedVecItem; -pub use managed_vec_item_nested_tuple::ManagedVecItemNestedTuple; +pub use managed_vec_item_nested_tuple::{ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit}; pub use managed_vec_item_payload::*; pub use managed_vec_owned_iter::ManagedVecOwnedIterator; pub use managed_vec_ref::ManagedVecRef; diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index 17c07f21a4..c0525ee0d5 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -133,6 +133,10 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + todo!() + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { Self::from_byte_reader(reader) } @@ -176,6 +180,10 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + todo!() + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { Self::from_byte_reader(reader) } diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 99dc7c6e87..c60df36991 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -87,6 +87,10 @@ impl ManagedVecItem for DebugHandle { use_raw_handle(RawHandle::from_byte_reader(reader)) } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + use_raw_handle(RawHandle::read_from_payload(payload)) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { From 6a6ff5c8ed77b853db951e2fa1afe8ac3aea3fa6 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Tue, 26 Nov 2024 13:49:38 +0200 Subject: [PATCH 019/133] sync mandos with v0.54.4 --- .../alloc-features/scenarios/alloc_mem_fail.scen.json | 2 +- .../alloc-features/scenarios/alloc_mem_leaking.scen.json | 2 +- .../basic-features/scenarios/crypto_verify_bls.scen.json | 2 +- .../scenarios/crypto_verify_bls_aggregated_signature.scen.json | 2 +- .../basic-features/scenarios/crypto_verify_bls_share.scen.json | 2 +- .../basic-features/scenarios/crypto_verify_secp256r1.scen.json | 2 +- .../scenarios/forwarder_call_async_retrieve_egld.scen.json | 2 +- .../scenarios/promises_call_async_retrieve_egld.scen.json | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/feature-tests/alloc-features/scenarios/alloc_mem_fail.scen.json b/contracts/feature-tests/alloc-features/scenarios/alloc_mem_fail.scen.json index 5185e53638..c8f86f7292 100644 --- a/contracts/feature-tests/alloc-features/scenarios/alloc_mem_fail.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/alloc_mem_fail.scen.json @@ -7,7 +7,7 @@ "sc:alloc-mem-fail": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-mem-fail.wasm" + "code": "mxsc:../output/alloc-mem-fail.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/alloc_mem_leaking.scen.json b/contracts/feature-tests/alloc-features/scenarios/alloc_mem_leaking.scen.json index 0cae3b7303..95f33ac733 100644 --- a/contracts/feature-tests/alloc-features/scenarios/alloc_mem_leaking.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/alloc_mem_leaking.scen.json @@ -7,7 +7,7 @@ "sc:alloc-mem-leaking": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-mem-leaking.wasm" + "code": "mxsc:../output/alloc-mem-leaking.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls.scen.json index fc67a3745b..99d683d28d 100644 --- a/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls.scen.json @@ -58,7 +58,7 @@ "expect": { "out": [], "status": "10", - "message": "str:err blsSignatureDeserialize 0032a2ddf341c08d1eb7232f05dc34e4454155e676b58c40fddf9a036562ac2c01533d2d557cb49d73aa9d7a89744696", + "message": "str:signature is invalid", "logs": "*", "gas": "*", "refund": "*" diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_aggregated_signature.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_aggregated_signature.scen.json index 546c0d4c9f..490fb1de8b 100644 --- a/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_aggregated_signature.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_aggregated_signature.scen.json @@ -70,7 +70,7 @@ "expect": { "out": [], "status": "10", - "message": "str:err blsSignatureDeserialize 0012858363e8caa5b398d3febdd7bc01bc2fae1fef8f486ff4d84a5f3342f2d38085904eb10b73c0879a45d23585ce8f", + "message": "str:signature is invalid", "logs": "*", "gas": "*", "refund": "*" diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_share.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_share.scen.json index fa7c21611b..2fe8473f52 100644 --- a/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_share.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_share.scen.json @@ -58,7 +58,7 @@ "expect": { "out": [], "status": "10", - "message": "str:err blsSignatureDeserialize ff725db195e37aa237cdbbda76270d4a229b6e7a3651104dc58c4349c0388e8546976fe54a04240530b99064e434c90f", + "message": "str:signature is invalid", "logs": "*", "gas": "*", "refund": "*" diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_verify_secp256r1.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_verify_secp256r1.scen.json index 1c35b46271..5d22d63d9c 100644 --- a/contracts/feature-tests/basic-features/scenarios/crypto_verify_secp256r1.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/crypto_verify_secp256r1.scen.json @@ -57,7 +57,7 @@ "expect": { "out": [], "status": "10", - "message": "str:signature verification failed", + "message": "str:signature is invalid", "logs": "*", "gas": "*", "refund": "*" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_egld.scen.json index f9091ab5a9..ecfae9b375 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_egld.scen.json @@ -84,7 +84,7 @@ "address": "sc:vault", "endpoint": "str:transferValueOnly", "topics": [ - "1000", + "", "sc:forwarder" ], "data": [ diff --git a/contracts/feature-tests/composability/scenarios/promises_call_async_retrieve_egld.scen.json b/contracts/feature-tests/composability/scenarios/promises_call_async_retrieve_egld.scen.json index bb8e199e91..e17b0fd7d5 100644 --- a/contracts/feature-tests/composability/scenarios/promises_call_async_retrieve_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_call_async_retrieve_egld.scen.json @@ -83,7 +83,7 @@ "address": "sc:vault", "endpoint": "str:transferValueOnly", "topics": [ - "1000", + "", "sc:forwarder" ], "data": [ From 3f400e2c1b3098f8b38e65ef44802c9749dff2ab Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Tue, 26 Nov 2024 17:12:52 +0100 Subject: [PATCH 020/133] impl write to/ read from state file in interactor and new set state function --- .../examples/adder/interactor/set_state.json | 82 +++++++++++++++++++ .../adder/interactor/src/basic_interactor.rs | 2 +- .../tests/basic_interactor_cs_test.rs | 36 +++++++- framework/snippets/Cargo.toml | 6 +- framework/snippets/src/account_tool.rs | 16 ++-- .../src/interactor/interactor_base.rs | 35 +++++++- .../interactor/interactor_chain_simulator.rs | 11 +++ .../gateway_chain_simulator_set_state.rs | 41 +++++++++- 8 files changed, 212 insertions(+), 17 deletions(-) create mode 100644 contracts/examples/adder/interactor/set_state.json diff --git a/contracts/examples/adder/interactor/set_state.json b/contracts/examples/adder/interactor/set_state.json new file mode 100644 index 0000000000..a5364326ab --- /dev/null +++ b/contracts/examples/adder/interactor/set_state.json @@ -0,0 +1,82 @@ +[ + { + "address": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "nonce": 5947, + "balance": "491982310359999986", + "keys": { + "454c524f4e446573647450544d2d35333666616201": "08021202000122ef0108011212546573742d5061696e742d486172766573741a20e32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed6020c4132a2e516d57564239575362674b52655a64615a434344766b454b70705a6b4d696d397563736e7857565041414c6a4374324368747470733a2f2f697066732e696f2f697066732f516d57564239575362674b52655a64615a434344766b454b70705a6b4d696d397563736e7857565041414c6a43743a3d746167733a3b6d657461646174613a516d52635039346b5872357a5a6a52477669376d4a36756e374c7078556859565234523452706963787a67596b74", + "454c524f4e44657364745453542d643964336136": "1209004563918244f40000", + "454c524f4e44657364745745474c442d613238633539": "120900389351ce08f09e12", + "454c524f4e44657364745453542d633636666535": "1209004563918244f40000", + "454c524f4e44657364745453542d623130616461": "1209004563918244f40000", + "454c524f4e4465736474475245454e2d306531363163": "120b00152d02c7e14af67fffdc", + "454c524f4e44657364745453542d656338383735": "12020064", + "454c524f4e44657364744c5453542d376266336431": "1209000de0b6b3a763fc19", + "454c524f4e44657364745453542d343265356138": "1209004563918244f40000", + "454c524f4e44726f6c656573647450544d2d353336666162": "0a1145534454526f6c654e46544372656174650a0f45534454526f6c654e46544275726e", + "454c524f4e44657364745453542d393836646663": "12020064", + "454c524f4e44657364745453542d323833633361": "12020064", + "454c524f4e4465736474424358535542542d33393264366172": "080112020001", + "454c524f4e44657364744c5453542d346638343965": "1209000de0b6b3a763fc19", + "454c524f4e44657364745453542d386564363538": "1209004563918244f40000", + "454c524f4e44657364745453542d343562383235": "12020064", + "454c524f4e446e6f6e636550544d2d353336666162": "01", + "454c524f4e44657364745453542d363835303064": "1209004563918244f40000", + "454c524f4e44657364745453542d336339363762": "12020064", + "454c524f4e446573647455544b2d313464353764": "120b0001e6ce88d5ebbfd00000", + "454c524f4e44657364745453542d363434633935": "12020064", + "454c524f4e44657364745453542d306632306637": "12020064", + "454c524f4e44657364745453542d333331386638": "1209004563918244f40000", + "454c524f4e44657364745453542d353538616434": "12020064", + "454c524f4e44657364745453542d363437383930": "1209004563918244f40000", + "454c524f4e44657364745453542d633933336139": "1209004563918244f40000", + "454c524f4e44657364745453542d393864633566": "1209004563918244f40000", + "454c524f4e44657364745453542d303637373232": "1209004563918244f40000", + "454c524f4e44657364745453542d346634303238": "12020064", + "454c524f4e44657364745453542d643862306438": "12020064", + "454c524f4e44657364745453542d346230653865": "1209004563918244f40000", + "454c524f4e44657364745453542d343138613232": "1209004563918244f40000", + "454c524f4e44657364745453542d396230323030": "1209004563918244f40000", + "454c524f4e44657364745453542d373639313337": "1209004563918244f40000", + "454c524f4e44657364745453542d303362373664": "12020064", + "454c524f4e44657364745453542d613562663131": "12020064", + "454c524f4e44657364745453542d353966316165": "1209004563918244f40000", + "454c524f4e44657364745453542d623136363735": "1209004563918244f40000", + "454c524f4e44657364745453542d333639646531": "1209004563918244f40000", + "454c524f4e44657364745453542d623830663863": "1209004563918244f40000", + "454c524f4e44657364745453542d633565303835": "1209004563918244f40000" + }, + "code": "", + "code_hash": "", + "root_hash": "2zSeJjLqgozEQmmgDU8L0/GidcKzJOlJgwoaTUqvDFg=", + "code_metadata": "", + "owner_address": "", + "developer_reward": "0" + }, + { + "address": "erd13x29rvmp4qlgn4emgztd8jgvyzdj0p6vn37tqxas3v9mfhq4dy7shalqrx", + "nonce": 1417, + "balance": "1753855617144056", + "keys": { + "454c524f4e446573647445564e544e4f544946592d393634383835": "120b00152d02c7e14af6800000", + "454c524f4e4465736474494e5445524e532d63393332356601": "0801120b0013097d1fb962e12fff47", + "454c524f4e44657364744e455453432d623635306261": "120b00d137965aa7a731800000", + "454c524f4e446e6f6e6365494e5445524e532d633933323566": "01", + "454c524f4e44657364745745474c442d613238633539": "120800010593b233281b", + "454c524f4e446e6f6e63654d4554414e46542d643062623339": "01", + "454c524f4e44726f6c6565736474494e5445524e532d633933323566": "0a1145534454526f6c654e46544372656174650a1645534454526f6c654e46544164645175616e74697479", + "454c524f4e44726f6c65657364744d4554414e46542d643062623339": "0a1145534454526f6c654e4654437265617465", + "454c524f4e446573647442534b2d343736343730": "120b00021e19e0c9bab23fff7b", + "454c524f4e44657364744e45543253432d306438663962": "120f0004ee2d6d3f3d6bcc25c64dc00000", + "454c524f4e4465736474424358535542542d3339326436616c": "080112020001", + "454c524f4e44657364744e4943552d393730323932": "120b00d3c21bcecceda1000000", + "454c524f4e4465736474424358535542542d3339326436616e": "080112020001" + }, + "code": "", + "code_hash": "", + "root_hash": "AJ2jyOcPXgZAl0kHAlbWZIlG3F1VDtcoLAHR6eqehBA=", + "code_metadata": "", + "owner_address": "", + "developer_reward": "0" + } +] \ No newline at end of file diff --git a/contracts/examples/adder/interactor/src/basic_interactor.rs b/contracts/examples/adder/interactor/src/basic_interactor.rs index 64dff9673e..fc08f50357 100644 --- a/contracts/examples/adder/interactor/src/basic_interactor.rs +++ b/contracts/examples/adder/interactor/src/basic_interactor.rs @@ -57,7 +57,7 @@ impl AdderInteract { let adder_owner_address = interactor.register_wallet(test_wallets::heidi()).await; let wallet_address = interactor.register_wallet(test_wallets::ivan()).await; - let _ = interactor.generate_blocks(30u64).await; + interactor.generate_blocks(30u64).await.unwrap(); AdderInteract { interactor, diff --git a/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs b/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs index d6b98b73e5..6d217f66f3 100644 --- a/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs +++ b/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs @@ -1,5 +1,5 @@ use basic_interactor::{AdderInteract, Config}; -use multiversx_sc_snippets::{sdk::gateway::SetStateAccount, test_wallets}; +use multiversx_sc_snippets::{imports::Bech32Address, sdk::gateway::SetStateAccount, test_wallets}; #[tokio::test] #[cfg_attr(not(feature = "chain-simulator-tests"), ignore)] @@ -61,3 +61,37 @@ async fn set_state_cs_test() { assert!(set_state_response.is_ok()); } + +#[tokio::test] +#[cfg_attr(not(feature = "chain-simulator-tests"), ignore)] +async fn set_state_from_file_cs_test() { + let account_address = test_wallets::mike(); + let account_address_2 = test_wallets::ivan(); + + let mut real_chain_interact = AdderInteract::new(Config::load_config()).await; + let simulator_interact = AdderInteract::new(Config::chain_simulator_config()).await; + + // now we should have current mike account in the set state file + real_chain_interact + .interactor + .retrieve_account(&Bech32Address::from(&account_address.to_address())) + .await; + + real_chain_interact + .interactor + .retrieve_account(&Bech32Address::from(&account_address_2.to_address())) + .await; + + let set_state_response = simulator_interact + .interactor + .set_state_for_saved_accounts() + .await; + + simulator_interact + .interactor + .generate_blocks(2u64) + .await + .unwrap(); + + assert!(set_state_response.is_ok()); +} diff --git a/framework/snippets/Cargo.toml b/framework/snippets/Cargo.toml index 54fe80f23f..a22b7fd721 100644 --- a/framework/snippets/Cargo.toml +++ b/framework/snippets/Cargo.toml @@ -27,8 +27,9 @@ log = "0.4.17" env_logger = "0.11" futures = "0.3" anyhow = "1.0.44" +serde_json = "1.0" -tokio = { version = "1.24", features = ["full"], optional = true} +tokio = { version = "1.24", features = ["full"], optional = true } [dependencies.multiversx-sc-scenario] version = "=0.54.1" @@ -52,6 +53,3 @@ default-features = false version = "=0.7.0" path = "../../sdk/dapp" optional = true - -[dev-dependencies] -serde_json = "1.0" diff --git a/framework/snippets/src/account_tool.rs b/framework/snippets/src/account_tool.rs index b0a5ccc220..eefc51642f 100644 --- a/framework/snippets/src/account_tool.rs +++ b/framework/snippets/src/account_tool.rs @@ -4,7 +4,7 @@ use multiversx_sc_scenario::{ imports::Bech32Address, scenario_model::{Account, BytesKey, BytesValue, Scenario, SetStateStep, Step}, }; -use multiversx_sdk::gateway::GatewayAsyncService; +use multiversx_sdk::gateway::{GatewayAsyncService, SetStateAccount}; use multiversx_sdk::gateway::{ GetAccountEsdtRolesRequest, GetAccountEsdtTokensRequest, GetAccountRequest, GetAccountStorageRequest, @@ -20,7 +20,7 @@ pub async fn print_account_as_scenario_set_state Scenario { pub async fn retrieve_account_as_scenario_set_state( api: &GatewayProxy, bech32_address: &Bech32Address, -) -> SetStateStep { +) -> (SetStateAccount, SetStateStep) { let address = bech32_address.as_address(); let sdk_account = api.request(GetAccountRequest::new(address)).await.unwrap(); @@ -63,14 +63,18 @@ pub async fn retrieve_account_as_scenario_set_state where @@ -85,9 +88,33 @@ where } pub async fn retrieve_account(&mut self, wallet_address: &Bech32Address) { - let set_state = retrieve_account_as_scenario_set_state(&self.proxy, wallet_address).await; - self.pre_runners.run_set_state_step(&set_state); - self.post_runners.run_set_state_step(&set_state); + let (set_state_account, set_state_step) = + retrieve_account_as_scenario_set_state(&self.proxy, wallet_address).await; + self.pre_runners.run_set_state_step(&set_state_step); + self.post_runners.run_set_state_step(&set_state_step); + + let path = self.get_state_file_path(); + set_state_account.add_to_state_file(path.as_path()); + } + + pub fn get_state_file_path(&self) -> PathBuf { + self.current_dir.join(INTERACTOR_SET_STATE_PATH) + } + + pub fn get_accounts_from_file(&self) -> Vec { + let file_path = self.get_state_file_path(); + + if !file_path.exists() { + return Vec::new(); + } + + let file = File::open(file_path).expect("Failed to open state file"); + let reader = BufReader::new(file); + + serde_json::from_reader(reader).unwrap_or_else(|_| { + println!("Failed to parse state file; returning an empty list of accounts"); + Vec::new() + }) } /// Tells the interactor where the crate lies relative to the workspace. diff --git a/framework/snippets/src/interactor/interactor_chain_simulator.rs b/framework/snippets/src/interactor/interactor_chain_simulator.rs index 17ca51f3a7..88fa701fe0 100644 --- a/framework/snippets/src/interactor/interactor_chain_simulator.rs +++ b/framework/snippets/src/interactor/interactor_chain_simulator.rs @@ -64,4 +64,15 @@ where .request(ChainSimulatorSetStateRequest::for_accounts(accounts)) .await } + + pub async fn set_state_for_saved_accounts(&self) -> Result { + if !self.use_chain_simulator { + return Ok(String::from("no-simulator")); + } + + let accounts = self.get_accounts_from_file(); + self.proxy + .request(ChainSimulatorSetStateRequest::for_accounts(accounts)) + .await + } } diff --git a/sdk/core/src/gateway/gateway_chain_simulator_set_state.rs b/sdk/core/src/gateway/gateway_chain_simulator_set_state.rs index 77b46d4422..284f00a709 100644 --- a/sdk/core/src/gateway/gateway_chain_simulator_set_state.rs +++ b/sdk/core/src/gateway/gateway_chain_simulator_set_state.rs @@ -1,6 +1,11 @@ use anyhow::anyhow; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; +use std::{ + collections::HashMap, + fs::{File, OpenOptions}, + io::{BufReader, BufWriter}, + path::Path, +}; use crate::data::account::Account; @@ -55,6 +60,40 @@ impl SetStateAccount { self } + + pub fn add_to_state_file(self, path: &Path) { + let mut accounts = if path.exists() { + let file = File::open(path) + .unwrap_or_else(|_| panic!("Failed to open state file at path {path:#?}")); + + let reader = BufReader::new(file); + + serde_json::from_reader::<_, Vec>(reader).unwrap_or_default() + } else { + Vec::new() + }; + + if let Some(existing_account) = accounts + .iter_mut() + .find(|account| account.address == self.address) + { + *existing_account = self; + } else { + accounts.push(self); + } + + let file = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(path) + .unwrap_or_else(|_| panic!("Failed to open or create state file at path {path:#?}")); + + let writer = BufWriter::new(file); + serde_json::to_writer_pretty(writer, &accounts).unwrap_or_else(|_| { + panic!("Failed to write updated state accounts to file at path {path:#?}") + }); + } } /// Sets state for a list of accounts using the chain simulator API. From 4acebb0c86283aa309602b6b2b6e1dc219ddbeb8 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Tue, 26 Nov 2024 23:31:32 +0200 Subject: [PATCH 021/133] VM Rust - fix transferValueOnly in async call --- chain/vm/src/tx_execution/exec_general_tx.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/chain/vm/src/tx_execution/exec_general_tx.rs b/chain/vm/src/tx_execution/exec_general_tx.rs index 2100e3fb20..d5e47d7b0f 100644 --- a/chain/vm/src/tx_execution/exec_general_tx.rs +++ b/chain/vm/src/tx_execution/exec_general_tx.rs @@ -1,3 +1,4 @@ +use num_bigint::BigUint; use num_traits::Zero; use crate::{ @@ -52,6 +53,19 @@ pub(crate) fn create_transfer_value_log(tx_input: &TxInput, call_type: CallType) let mut data = vec![call_type.to_log_bytes(), tx_input.func_name.to_bytes()]; data.append(&mut tx_input.args.clone()); + if tx_input.esdt_values.is_empty() { + if !tx_input.callback_payments.egld_value.is_zero() + && tx_input.call_type == CallType::AsyncCallback + { + return TxLog { + address: tx_input.from.clone(), + endpoint: "transferValueOnly".into(), + topics: vec![b"".to_vec(), tx_input.to.to_vec()], + data, + }; + } + } + let egld_value = if tx_input.call_type == CallType::AsyncCallback { &tx_input.callback_payments.egld_value } else { From 8c6ae73f34dab9eab91d13687ad29bf91e76f628 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Tue, 26 Nov 2024 23:35:04 +0200 Subject: [PATCH 022/133] clippy fix --- chain/vm/src/tx_execution/exec_general_tx.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/chain/vm/src/tx_execution/exec_general_tx.rs b/chain/vm/src/tx_execution/exec_general_tx.rs index d5e47d7b0f..abf4d4344e 100644 --- a/chain/vm/src/tx_execution/exec_general_tx.rs +++ b/chain/vm/src/tx_execution/exec_general_tx.rs @@ -1,4 +1,3 @@ -use num_bigint::BigUint; use num_traits::Zero; use crate::{ From bb59ac16455067aaf3c8d177080583f997fbfc07 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 01:15:13 +0200 Subject: [PATCH 023/133] ManagedVecItem payload refactor - more attempts, read_from_payload impl --- .../src/types/managed/wrapped/managed_vec.rs | 18 ++-- .../types/managed/wrapped/managed_vec_item.rs | 101 ++++++++++++++++-- .../wrapped/managed_vec_item_nested_tuple.rs | 18 ++++ .../wrapped/managed_vec_item_payload.rs | 69 +++++++++--- .../managed/wrapped/managed_vec_owned_iter.rs | 16 +-- .../base/src/types/managed/wrapped/mod.rs | 6 +- .../derive/src/managed_vec_item_derive.rs | 32 +++++- 7 files changed, 215 insertions(+), 45 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index d3212e4d03..475bc300d3 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -1,4 +1,4 @@ -use super::EncodedManagedVecItem; +use super::{EncodedManagedVecItem, ManagedVecItemPayload}; use crate::{ abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::{ErrorApiImpl, InvalidSliceError, ManagedTypeApi}, @@ -187,15 +187,15 @@ where pub(super) unsafe fn get_unsafe(&self, index: usize) -> T { let byte_index = index * T::payload_size(); - let mut load_result = Ok(()); - let result = T::from_byte_reader(|dest_slice| { - load_result = self.buffer.load_slice(byte_index, dest_slice); - }); - - match load_result { - Ok(_) => result, - Err(_) => M::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_MSG), + let mut payload = T::PAYLOAD::new_buffer(); + if self + .buffer + .load_slice(byte_index, payload.payload_slice_mut()) + .is_err() + { + M::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_MSG); } + T::read_from_payload(&payload) } pub fn set(&mut self, index: usize, item: T) -> Result<(), InvalidSliceError> { diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 8c06da18c3..484a106d41 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -10,7 +10,10 @@ use crate::{ }, }; -use super::{ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, ManagedVecItemPayload, ManagedVecItemPayloadBuffer}; +use super::{ + ManagedVecItemEmptyPayload, ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, + ManagedVecItemPayload, ManagedVecItemPayloadAdd, ManagedVecItemPayloadBuffer, +}; /// Types that implement this trait can be items inside a `ManagedVec`. /// All these types need a payload, i.e a representation that gets stored @@ -67,6 +70,16 @@ pub trait ManagedVecItem: 'static { fn into_byte_writer R>(self, writer: Writer) -> R; } +pub unsafe fn managed_vec_item_read_from_payload_index(payload: &P, index: &mut usize) -> T +where + T: ManagedVecItem, + P: ManagedVecItemPayload, +{ + let value = T::read_from_payload(payload.slice_unchecked(*index)); + *index += T::PAYLOAD::payload_size(); + value +} + macro_rules! impl_int { ($ty:ident, $payload_size:expr) => { impl ManagedVecItem for $ty { @@ -161,9 +174,12 @@ impl ManagedVecItem for bool { impl ManagedVecItem for Option where (u8, (T, ())): ManagedVecItemNestedTuple, + ManagedVecItemPayloadBuffer<1>: ManagedVecItemPayloadAdd, T: ManagedVecItem, { - type PAYLOAD = <(u8, (T, ())) as ManagedVecItemNestedTuple>::PAYLOAD; + // type PAYLOAD = <(u8, (T, ())) as ManagedVecItemNestedTuple>::PAYLOAD; + type PAYLOAD = as ManagedVecItemPayloadAdd>::Output; + // type PAYLOAD = EquivPayload<(u8, T)>; const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; @@ -182,13 +198,26 @@ where fn read_from_payload(payload: &Self::PAYLOAD) -> Self { // let (p1, (p2, ())) = <(u8, (T, ()))>::split_all(payload); - + + // let (p1, p2) = as ManagedVecItemPayloadAdd< + // T::PAYLOAD, + // >>::split_from_add(payload); + // let disc = u8::read_from_payload(p1); - // let x = split_payload(payload); - // Self::PAYLOAD::spli - todo!() - // let (disc_payload, t_payload) = payload.split::<1>(); - // let x = payload; + // if disc == 0 { + // None + // } else { + // Some(T::read_from_payload(p2)) + // } + + unsafe { + let disc = u8::read_from_payload(payload.slice_unchecked(0)); + if disc == 0 { + None + } else { + Some(T::read_from_payload(payload.slice_unchecked(1))) + } + } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( @@ -363,3 +392,59 @@ impl ManagedVecItem for EsdtLocalRole { ::into_byte_writer(self.as_u16(), writer) } } + +impl ManagedVecItem for () { + type PAYLOAD = ManagedVecItemEmptyPayload; + + const SKIPS_RESERIALIZATION: bool = true; + + type Ref<'a> = Self; + + fn from_byte_reader(reader: Reader) -> Self { + () + } + + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + () + } + + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( + _reader: Reader, + ) -> Self::Ref<'a> { + () + } + + fn into_byte_writer R>(self, writer: Writer) -> R { + todo!() + } +} + +impl ManagedVecItem for (Head, Tail) +where + Head: ManagedVecItem + 'static, + Tail: ManagedVecItem + 'static, +{ + type PAYLOAD = ManagedVecItemEmptyPayload; + + const SKIPS_RESERIALIZATION: bool = true; + + type Ref<'a> = Self; + + fn from_byte_reader(reader: Reader) -> Self { + todo!() + } + + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + todo!() + } + + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( + reader: Reader, + ) -> Self::Ref<'a> { + todo!() + } + + fn into_byte_writer R>(self, writer: Writer) -> R { + todo!() + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs index 45e6a8d820..7c64920cf3 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs @@ -86,6 +86,8 @@ where #[cfg(test)] pub mod tests { + use crate::types::ManagedVecItemPayloadBuffer; + use super::*; #[test] @@ -100,4 +102,20 @@ pub mod tests { fn assert_payload_size(expected_size: usize) { assert_eq!(N::PAYLOAD::payload_size(), expected_size); } + + #[test] + fn split_all_test() { + let p = ManagedVecItemPayloadBuffer::new_buffer(); + let (p1, (p2, ())) = <(u16, (u32, ()))>::split_all(&p); + } + + // fn split_all_t() + // where + // T: ManagedVecItem, + // ManagedVecItemPayloadBuffer<1>: ManagedVecItemPayloadAdd, + // (u16, (T, ())): ManagedVecItemNestedTuple, + // { + // let p = ManagedVecItemPayloadBuffer::new_buffer(); + // let (p1, (p2, ())) = <(u16, (T, ()))>::split_all(&p); + // } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index 4fcc20d9d3..ba2d7e1296 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -1,5 +1,7 @@ use core::marker::PhantomData; +use super::ManagedVecItem; + /// Describes the binary represetnation of a ManagedVecItem. /// /// It is always an array that can be allocated directly on stack. @@ -11,6 +13,8 @@ pub trait ManagedVecItemPayload { fn payload_slice(&self) -> &[u8]; fn payload_slice_mut(&mut self) -> &mut [u8]; + + unsafe fn slice_unchecked(&self, index: usize) -> &S; } /// Empty ManagedVecItem. @@ -34,6 +38,10 @@ impl ManagedVecItemPayload for ManagedVecItemEmptyPayload { fn payload_slice_mut(&mut self) -> &mut [u8] { &mut [] } + + unsafe fn slice_unchecked(&self, index: usize) -> &S { + unimplemented!() + } } /// The main ManagedVecItemPayload implementation. Uses an array in its implementation. @@ -58,6 +66,11 @@ impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { fn payload_slice_mut(&mut self) -> &mut [u8] { &mut self.buffer[..] } + + unsafe fn slice_unchecked(&self, index: usize) -> &S { + let ptr = self.buffer.as_ptr().offset(index as isize); + core::mem::transmute(ptr) + } } #[repr(transparent)] @@ -97,6 +110,10 @@ where fn payload_slice_mut(&mut self) -> &mut [u8] { self.buffer.payload_slice_mut() } + + unsafe fn slice_unchecked(&self, index: usize) -> &S { + self.buffer.slice_unchecked(index) + } } impl ManagedVecItemPayloadConcat @@ -116,25 +133,44 @@ where P0: ManagedVecItemPayloadAdd<>::Output>, { type Output = ManagedVecItemPayloadConcat>; - + fn split_from_add(payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { todo!() } +} + +pub struct ManagedVecItemPayloadEquiv +where + T: ManagedVecItem, +{ + equiv: T::PAYLOAD, +} + +impl ManagedVecItemPayload for ManagedVecItemPayloadEquiv +where + T: ManagedVecItem, +{ + fn new_buffer() -> Self { + ManagedVecItemPayloadEquiv { + equiv: ManagedVecItemPayload::new_buffer(), + } + } + fn payload_size() -> usize { + T::PAYLOAD::payload_size() + } - - // fn split_from_add( - // payload: &ManagedVecItemPayloadBuffer<$result_add>, - // ) -> ( - // &ManagedVecItemPayloadBuffer<$dec1>, - // &ManagedVecItemPayloadBuffer<$dec2>, - // ) { - // unsafe { - // let ptr1 = payload.buffer.as_ptr(); - // let ptr2 = ptr1.offset($dec1 as isize); - // (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) - // } - // } + fn payload_slice(&self) -> &[u8] { + self.equiv.payload_slice() + } + + fn payload_slice_mut(&mut self) -> &mut [u8] { + self.equiv.payload_slice_mut() + } + + unsafe fn slice_unchecked(&self, index: usize) -> &S { + self.equiv.slice_unchecked(index) + } } /// Describes concatantion of smaller payloads into a larger one. @@ -151,8 +187,9 @@ where fn split_from_add(payload: &Self::Output) -> (&Self, &Rhs); } -impl ManagedVecItemPayloadAdd - for ManagedVecItemPayloadBuffer +impl

ManagedVecItemPayloadAdd for P +where + P: ManagedVecItemPayload, { type Output = Self; diff --git a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs index 20942e70d4..470bd16053 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs @@ -1,6 +1,6 @@ use crate::api::ManagedTypeApi; -use super::{ManagedVec, ManagedVecItem}; +use super::{ManagedVec, ManagedVecItem, ManagedVecItemPayload}; impl<'a, M, T> IntoIterator for &'a ManagedVec where @@ -52,15 +52,15 @@ where if next_byte_start > self.byte_end { return None; } - let result = T::from_byte_reader(|dest_slice| { - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_start, dest_slice); - }); + + let mut payload = T::PAYLOAD::new_buffer(); + let _ = self + .managed_vec + .buffer + .load_slice(self.byte_start, payload.payload_slice_mut()); self.byte_start = next_byte_start; - Some(result) + Some(T::read_from_payload(&payload)) } fn size_hint(&self) -> (usize, Option) { diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped/mod.rs index f4db4e5212..38d721812e 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -46,8 +46,10 @@ pub use managed_option::ManagedOption; pub use managed_ref::ManagedRef; pub use managed_ref_mut::ManagedRefMut; pub use managed_vec::ManagedVec; -pub use managed_vec_item::ManagedVecItem; -pub use managed_vec_item_nested_tuple::{ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit}; +pub use managed_vec_item::{managed_vec_item_read_from_payload_index, ManagedVecItem}; +pub use managed_vec_item_nested_tuple::{ + ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, +}; pub use managed_vec_item_payload::*; pub use managed_vec_owned_iter::ManagedVecOwnedIterator; pub use managed_vec_ref::ManagedVecRef; diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index c0525ee0d5..d5b91d2fbf 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -66,6 +66,24 @@ fn generate_from_byte_reader_snippets(fields: &syn::Fields) -> Vec Vec { + match fields { + syn::Fields::Named(fields_named) => fields_named + .named + .iter() + .map(|field| { + let field_ident = &field.ident; + quote! { + #field_ident: multiversx_sc::types::managed_vec_item_read_from_payload_index(payload, &mut index), + } + }) + .collect(), + _ => { + panic!("ManagedVecItem only supports named fields") + } + } +} + fn generate_to_byte_writer_snippets(fields: &syn::Fields) -> Vec { match fields { syn::Fields::Named(fields_named) => fields_named @@ -134,7 +152,10 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream } fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - todo!() + let discriminant = ::read_from_payload(payload); + match discriminant { + #(#reader_match_arms)* + } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { @@ -160,6 +181,7 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token let skips_reserialization_snippets = generate_skips_reserialization_snippets(&data_struct.fields); let from_byte_reader_snippets = generate_from_byte_reader_snippets(&data_struct.fields); + let read_from_payload_snippets = generate_read_from_payload_snippets(&data_struct.fields); let to_byte_writer_snippets = generate_to_byte_writer_snippets(&data_struct.fields); let payload_buffer_snippet = generate_payload_buffer_snippet(); @@ -181,7 +203,13 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token } fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - todo!() + let mut index = 0; + + unsafe { + #name { + #(#read_from_payload_snippets)* + } + } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { From 08b47efbdea818e49277463aa89e57082b0e648d Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 01:32:31 +0200 Subject: [PATCH 024/133] ManagedVecItem payload refactor - cleanup --- .../managed/wrapped/esdt_token_payment.rs | 11 ++- .../types/managed/wrapped/managed_vec_item.rs | 93 ++----------------- .../wrapped/managed_vec_item_nested_tuple.rs | 2 +- .../wrapped/managed_vec_item_payload.rs | 58 +----------- 4 files changed, 22 insertions(+), 142 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index a92a9cbe16..83369820c2 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -13,7 +13,7 @@ use crate::{ derive::type_abi, }; -use super::{ManagedVec, ManagedVecItemPayloadBuffer}; +use super::{managed_vec_item_read_from_payload_index, ManagedVec, ManagedVecItemPayloadBuffer}; #[type_abi] #[derive(TopEncode, NestedEncode, Clone, PartialEq, Eq, Debug)] @@ -206,7 +206,14 @@ impl ManagedVecItem for EsdtTokenPayment { } fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - todo!() + let mut index = 0; + unsafe { + EsdtTokenPayment { + token_identifier: managed_vec_item_read_from_payload_index(payload, &mut index), + token_nonce: managed_vec_item_read_from_payload_index(payload, &mut index), + amount: managed_vec_item_read_from_payload_index(payload, &mut index), + } + } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 484a106d41..19d714d7b9 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -10,10 +10,7 @@ use crate::{ }, }; -use super::{ - ManagedVecItemEmptyPayload, ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, - ManagedVecItemPayload, ManagedVecItemPayloadAdd, ManagedVecItemPayloadBuffer, -}; +use super::{ManagedVecItemPayload, ManagedVecItemPayloadAdd, ManagedVecItemPayloadBuffer}; /// Types that implement this trait can be items inside a `ManagedVec`. /// All these types need a payload, i.e a representation that gets stored @@ -173,13 +170,10 @@ impl ManagedVecItem for bool { impl ManagedVecItem for Option where - (u8, (T, ())): ManagedVecItemNestedTuple, ManagedVecItemPayloadBuffer<1>: ManagedVecItemPayloadAdd, T: ManagedVecItem, { - // type PAYLOAD = <(u8, (T, ())) as ManagedVecItemNestedTuple>::PAYLOAD; type PAYLOAD = as ManagedVecItemPayloadAdd>::Output; - // type PAYLOAD = EquivPayload<(u8, T)>; const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; @@ -197,26 +191,15 @@ where } fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - // let (p1, (p2, ())) = <(u8, (T, ()))>::split_all(payload); - - // let (p1, p2) = as ManagedVecItemPayloadAdd< - // T::PAYLOAD, - // >>::split_from_add(payload); - - // let disc = u8::read_from_payload(p1); - // if disc == 0 { - // None - // } else { - // Some(T::read_from_payload(p2)) - // } - - unsafe { - let disc = u8::read_from_payload(payload.slice_unchecked(0)); - if disc == 0 { - None - } else { - Some(T::read_from_payload(payload.slice_unchecked(1))) - } + let (p1, p2) = as ManagedVecItemPayloadAdd< + T::PAYLOAD, + >>::split_from_add(payload); + + let disc = u8::read_from_payload(p1); + if disc == 0 { + None + } else { + Some(T::read_from_payload(p2)) } } @@ -392,59 +375,3 @@ impl ManagedVecItem for EsdtLocalRole { ::into_byte_writer(self.as_u16(), writer) } } - -impl ManagedVecItem for () { - type PAYLOAD = ManagedVecItemEmptyPayload; - - const SKIPS_RESERIALIZATION: bool = true; - - type Ref<'a> = Self; - - fn from_byte_reader(reader: Reader) -> Self { - () - } - - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - () - } - - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - _reader: Reader, - ) -> Self::Ref<'a> { - () - } - - fn into_byte_writer R>(self, writer: Writer) -> R { - todo!() - } -} - -impl ManagedVecItem for (Head, Tail) -where - Head: ManagedVecItem + 'static, - Tail: ManagedVecItem + 'static, -{ - type PAYLOAD = ManagedVecItemEmptyPayload; - - const SKIPS_RESERIALIZATION: bool = true; - - type Ref<'a> = Self; - - fn from_byte_reader(reader: Reader) -> Self { - todo!() - } - - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - todo!() - } - - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - todo!() - } - - fn into_byte_writer R>(self, writer: Writer) -> R { - todo!() - } -} diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs index 7c64920cf3..1e8b5511a4 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs @@ -106,7 +106,7 @@ pub mod tests { #[test] fn split_all_test() { let p = ManagedVecItemPayloadBuffer::new_buffer(); - let (p1, (p2, ())) = <(u16, (u32, ()))>::split_all(&p); + let (_p1, (_p2, ())) = <(u16, (u32, ()))>::split_all(&p); } // fn split_all_t() diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index ba2d7e1296..31210dd714 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -39,7 +39,7 @@ impl ManagedVecItemPayload for ManagedVecItemEmptyPayload { &mut [] } - unsafe fn slice_unchecked(&self, index: usize) -> &S { + unsafe fn slice_unchecked(&self, _index: usize) -> &S { unimplemented!() } } @@ -134,7 +134,7 @@ where { type Output = ManagedVecItemPayloadConcat>; - fn split_from_add(payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { + fn split_from_add(_payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { todo!() } } @@ -198,27 +198,6 @@ where } } -pub trait ManagedVecItemPayloadSplit: ManagedVecItemPayload { - type P1: ManagedVecItemPayload; - type P2: ManagedVecItemPayload; - - fn split_impl(&self) -> (&Self::P1, &Self::P2); -} - -impl ManagedVecItemPayloadBuffer { - pub fn split_me( - &self, - ) -> ( - &>::P1, - &>::P2, - ) - where - Self: ManagedVecItemPayloadSplit, - { - ManagedVecItemPayloadSplit::::split_impl(self) - } -} - /// Replaces a const generic expression. /// /// Remove once const generic expressions are stabilized in Rust. @@ -242,42 +221,9 @@ macro_rules! payload_add { } } } - - impl ManagedVecItemPayloadSplit<$dec1> for ManagedVecItemPayloadBuffer<$result_add> { - type P1 = ManagedVecItemPayloadBuffer<$dec1>; - type P2 = ManagedVecItemPayloadBuffer<$dec2>; - - fn split_impl( - &self, - ) -> ( - &ManagedVecItemPayloadBuffer<$dec1>, - &ManagedVecItemPayloadBuffer<$dec2>, - ) { - unsafe { - let ptr1 = self.buffer.as_ptr(); - let ptr2 = ptr1.offset($dec1 as isize); - (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) - } - } - } }; } -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn payload_split() { - let payload = ManagedVecItemPayloadBuffer { - buffer: [1, 2, 3, 4, 5], - }; - let (p1, p2) = payload.split_me::<3>(); - assert_eq!(p1.buffer, [1, 2, 3]); - assert_eq!(p2.buffer, [4, 5]); - } -} - payload_add!(1usize, 1usize, 2usize); payload_add!(1usize, 2usize, 3usize); payload_add!(1usize, 3usize, 4usize); From 58090a1aa0a3d252408ab209ff9dd3451db20c2d Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 02:12:29 +0200 Subject: [PATCH 025/133] ManagedVecItem payload refactor - borrow_from_payload impl --- .../esdt_token_payment_multi_value.rs | 5 +++ .../managed/wrapped/esdt_token_payment.rs | 5 +++ .../types/managed/wrapped/managed_option.rs | 8 +++- .../src/types/managed/wrapped/managed_vec.rs | 19 +++++---- .../types/managed/wrapped/managed_vec_item.rs | 41 +++++++++++++++++++ .../wrapped/managed_vec_item_nested_tuple.rs | 4 +- .../managed/wrapped/managed_vec_owned_iter.rs | 13 +++--- .../managed/wrapped/managed_vec_ref_iter.rs | 34 +++++++-------- .../derive/src/managed_vec_item_derive.rs | 9 ++++ .../src/api/impl_vh/debug_handle_vh.rs | 4 ++ 10 files changed, 103 insertions(+), 39 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 4eb6fc60d8..07cf680de0 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -52,6 +52,11 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { EsdtTokenPayment::read_from_payload(payload).into() } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: managed ref + Self::read_from_payload(payload) + } + #[inline] unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 83369820c2..b0a62679b8 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -216,6 +216,11 @@ impl ManagedVecItem for EsdtTokenPayment { } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: managed ref + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index ae77c6bc92..add7ae2669 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -209,7 +209,13 @@ where } fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - Self::new_with_handle(use_raw_handle(i32::read_from_payload(payload))) + let handle = use_raw_handle(i32::read_from_payload(payload)); + Self::new_with_handle(handle) + } + + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: managed ref + Self::read_from_payload(payload) } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 475bc300d3..de84d66904 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -141,15 +141,16 @@ where pub fn try_get(&self, index: usize) -> Option> { let byte_index = index * T::payload_size(); - let mut load_result = Ok(()); - let result = unsafe { - T::from_byte_reader_as_borrow(|dest_slice| { - load_result = self.buffer.load_slice(byte_index, dest_slice); - }) - }; - match load_result { - Ok(_) => Some(result), - Err(_) => None, + + let mut payload = T::PAYLOAD::new_buffer(); + if self + .buffer + .load_slice(byte_index, payload.payload_slice_mut()) + .is_ok() + { + unsafe { Some(T::borrow_from_payload(&payload)) } + } else { + None } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 19d714d7b9..87e8bc3094 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -46,6 +46,8 @@ pub trait ManagedVecItem: 'static { fn read_from_payload(payload: &Self::PAYLOAD) -> Self; + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a>; + /// Parses given bytes as a representation of the object, either owned, or a reference. /// /// # Safety @@ -94,6 +96,10 @@ macro_rules! impl_int { $ty::from_be_bytes(payload.buffer) } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + $ty::from_be_bytes(payload.buffer) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -129,6 +135,10 @@ impl ManagedVecItem for usize { u32::read_from_payload(payload) as usize } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -154,6 +164,10 @@ impl ManagedVecItem for bool { u8::read_from_payload(payload) > 0 } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -203,6 +217,10 @@ where } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -239,6 +257,11 @@ macro_rules! impl_managed_type { unsafe { Self::from_handle(handle) } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + let handle = use_raw_handle(i32::read_from_payload(payload)); + ManagedRef::wrap_handle(handle) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -279,6 +302,11 @@ where unsafe { Self::from_handle(handle) } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + let handle = use_raw_handle(i32::read_from_payload(payload)); + ManagedRef::wrap_handle(handle) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -313,6 +341,11 @@ where unsafe { Self::from_handle(handle) } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + let handle = use_raw_handle(i32::read_from_payload(payload)); + ManagedRef::wrap_handle(handle) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -341,6 +374,10 @@ impl ManagedVecItem for EsdtTokenType { u8::read_from_payload(payload).into() } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -365,6 +402,10 @@ impl ManagedVecItem for EsdtLocalRole { u16::read_from_payload(payload).into() } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs index 1e8b5511a4..11a7055a40 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs @@ -31,9 +31,7 @@ impl ManagedVecItemNestedTuple for () { impl<'a> ManagedVecItemNestedTupleSplit<'a> for () { type S = (); - fn split_all(_payload: &'a Self::PAYLOAD) -> Self::S { - () - } + fn split_all(_payload: &'a Self::PAYLOAD) -> Self::S {} } impl ManagedVecItemNestedTuple for (Head, Tail) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs index 470bd16053..8e0da8727c 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs @@ -88,14 +88,13 @@ where } self.byte_end -= T::payload_size(); - let result = T::from_byte_reader(|dest_slice| { - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_end, dest_slice); - }); + let mut payload = T::PAYLOAD::new_buffer(); + let _ = self + .managed_vec + .buffer + .load_slice(self.byte_end, payload.payload_slice_mut()); - Some(result) + Some(T::read_from_payload(&payload)) } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs index ad04b5eaf4..4703a1f61b 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs @@ -1,6 +1,6 @@ use crate::api::ManagedTypeApi; -use super::{ManagedVec, ManagedVecItem}; +use super::{ManagedVec, ManagedVecItem, ManagedVecItemPayload}; pub struct ManagedVecRefIterator<'a, M, T> where @@ -38,17 +38,16 @@ where if next_byte_start > self.byte_end { return None; } - let result = unsafe { - T::from_byte_reader_as_borrow(|dest_slice| { - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_start, dest_slice); - }) - }; + + let mut payload = T::PAYLOAD::new_buffer(); + let _ = self + .managed_vec + .buffer + .load_slice(self.byte_start, payload.payload_slice_mut()); self.byte_start = next_byte_start; - Some(result) + + unsafe { Some(T::borrow_from_payload(&payload)) } } fn size_hint(&self) -> (usize, Option) { @@ -75,16 +74,13 @@ where } self.byte_end -= T::payload_size(); - let result = unsafe { - T::from_byte_reader_as_borrow(|dest_slice| { - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_end, dest_slice); - }) - }; + let mut payload = T::PAYLOAD::new_buffer(); + let _ = self + .managed_vec + .buffer + .load_slice(self.byte_end, payload.payload_slice_mut()); - Some(result) + unsafe { Some(T::borrow_from_payload(&payload)) } } } diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index d5b91d2fbf..1b1d41fe69 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -158,6 +158,10 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { Self::from_byte_reader(reader) } @@ -212,6 +216,11 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: managed ref + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { Self::from_byte_reader(reader) } diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index c60df36991..4a6d38b212 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -91,6 +91,10 @@ impl ManagedVecItem for DebugHandle { use_raw_handle(RawHandle::read_from_payload(payload)) } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { From b6c31f1a49400cb9475dcd67879f0f8480052f92 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 02:12:55 +0200 Subject: [PATCH 026/133] clippy fix --- .../src/types/managed/wrapped/managed_vec_item.rs | 5 +++++ .../types/managed/wrapped/managed_vec_item_payload.rs | 11 +++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 87e8bc3094..512e2d847d 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -46,6 +46,11 @@ pub trait ManagedVecItem: 'static { fn read_from_payload(payload: &Self::PAYLOAD) -> Self; + /// Parses given bytes as a representation of the object, either owned, or a reference. + /// + /// # Safety + /// + /// In certain cases this involves practically disregarding the lifetimes, hence it is unsafe. unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a>; /// Parses given bytes as a representation of the object, either owned, or a reference. diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index 31210dd714..4d336632cf 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -68,8 +68,8 @@ impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { } unsafe fn slice_unchecked(&self, index: usize) -> &S { - let ptr = self.buffer.as_ptr().offset(index as isize); - core::mem::transmute(ptr) + let ptr = self.buffer.as_ptr().add(index); + &*ptr.cast::() } } @@ -216,8 +216,11 @@ macro_rules! payload_add { ) { unsafe { let ptr1 = payload.buffer.as_ptr(); - let ptr2 = ptr1.offset($dec1 as isize); - (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) + let ptr2 = ptr1.add($dec1); + ( + &*ptr1.cast::>(), + &*ptr2.cast::>(), + ) } } } From 50c674ce67eaf8cc739c083fdb3d0f467bec2f83 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 02:20:07 +0200 Subject: [PATCH 027/133] ManagedVecItem payload refactor - remove from_byte_reader_as_borrow --- .../esdt_token_payment_multi_value.rs | 7 -- .../managed/wrapped/esdt_token_payment.rs | 6 -- .../types/managed/wrapped/managed_option.rs | 6 +- .../types/managed/wrapped/managed_vec_item.rs | 66 ------------------- .../derive/src/managed_vec_item_derive.rs | 8 --- .../src/api/impl_vh/debug_handle_vh.rs | 6 -- 6 files changed, 1 insertion(+), 98 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 07cf680de0..299bc8bfc2 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -57,13 +57,6 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { Self::read_from_payload(payload) } - #[inline] - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - #[inline] fn into_byte_writer R>(self, writer: Writer) -> R { self.obj.into_byte_writer(writer) diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index b0a62679b8..80d4cc0858 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -221,12 +221,6 @@ impl ManagedVecItem for EsdtTokenPayment { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { let mut arr: [u8; 16] = [0u8; 16]; let mut index = 0; diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index add7ae2669..03af276bc9 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -218,11 +218,7 @@ where Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } + fn into_byte_writer R>(self, writer: Writer) -> R { ::into_byte_writer(self.handle, writer) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 512e2d847d..c9b59721f2 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -53,15 +53,6 @@ pub trait ManagedVecItem: 'static { /// In certain cases this involves practically disregarding the lifetimes, hence it is unsafe. unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a>; - /// Parses given bytes as a representation of the object, either owned, or a reference. - /// - /// # Safety - /// - /// In certain cases this involves practically disregarding the lifetimes, hence it is unsafe. - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a>; - /// Converts the object into bytes. /// /// The output is processed by the `writer` lambda. @@ -105,12 +96,6 @@ macro_rules! impl_int { $ty::from_be_bytes(payload.buffer) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { let bytes = self.to_be_bytes(); writer(&bytes) @@ -144,12 +129,6 @@ impl ManagedVecItem for usize { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { let bytes = (self as u32).to_be_bytes(); writer(&bytes) @@ -173,12 +152,6 @@ impl ManagedVecItem for bool { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, writer: Writer) -> R { // true -> 1u8 // false -> 0u8 @@ -226,12 +199,6 @@ where Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { let mut payload = Self::PAYLOAD::new_buffer(); let slice = payload.payload_slice_mut(); @@ -267,13 +234,6 @@ macro_rules! impl_managed_type { ManagedRef::wrap_handle(handle) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - let handle = <$ty as ManagedType>::OwnHandle::from_byte_reader(reader); - ManagedRef::wrap_handle(handle) - } - fn into_byte_writer R>(self, writer: Writer) -> R { let handle = unsafe { self.forget_into_handle() }; <$ty as ManagedType>::OwnHandle::into_byte_writer(handle, writer) @@ -312,13 +272,6 @@ where ManagedRef::wrap_handle(handle) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - let handle = >::OwnHandle::from_byte_reader(reader); - ManagedRef::wrap_handle(handle) - } - fn into_byte_writer R>(self, writer: Writer) -> R { <>::OwnHandle as ManagedVecItem>::into_byte_writer( self.get_handle(), @@ -351,13 +304,6 @@ where ManagedRef::wrap_handle(handle) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - let handle = M::ManagedBufferHandle::from_byte_reader(reader); - ManagedRef::wrap_handle(handle) - } - fn into_byte_writer R>(self, writer: Writer) -> R { let handle = unsafe { self.forget_into_handle() }; ::into_byte_writer(handle, writer) @@ -383,12 +329,6 @@ impl ManagedVecItem for EsdtTokenType { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { writer(&[self.as_u8()]) } @@ -411,12 +351,6 @@ impl ManagedVecItem for EsdtLocalRole { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, writer: Writer) -> R { ::into_byte_writer(self.as_u16(), writer) } diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index 1b1d41fe69..c45d5550c2 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -162,10 +162,6 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { let mut arr: [u8; 1] = [0u8; 1]; arr[0] = match self { @@ -221,10 +217,6 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { #payload_buffer_snippet let mut index = 0; diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 4a6d38b212..8193c36331 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -95,12 +95,6 @@ impl ManagedVecItem for DebugHandle { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - use_raw_handle(RawHandle::from_byte_reader(reader)) - } - fn into_byte_writer R>(self, writer: Writer) -> R { RawHandle::into_byte_writer(self.get_raw_handle(), writer) } From 348f046823ecf035390cf488249d9ace87f150a4 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 02:39:41 +0200 Subject: [PATCH 028/133] ManagedVecItem payload refactor - remove read_from_payload --- .../esdt_token_payment_multi_value.rs | 4 -- .../wrapped/encoded_managed_vec_item.rs | 6 +- .../managed/wrapped/esdt_token_payment.rs | 27 --------- .../types/managed/wrapped/managed_option.rs | 7 --- .../src/types/managed/wrapped/managed_vec.rs | 16 ++++-- .../types/managed/wrapped/managed_vec_item.rs | 56 ------------------- .../wrapped/managed_vec_item_payload.rs | 6 ++ .../derive/src/managed_vec_item_derive.rs | 42 -------------- .../src/api/impl_vh/debug_handle_vh.rs | 4 -- .../derive_managed_vec_item_biguint_test.rs | 10 +--- ...anaged_vec_item_esdt_token_payment_test.rs | 10 +--- .../derive_managed_vec_item_simple_enum.rs | 5 +- .../derive_managed_vec_item_struct_1_test.rs | 6 +- .../derive_managed_vec_item_struct_2_test.rs | 6 +- 14 files changed, 26 insertions(+), 179 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 299bc8bfc2..7479df9381 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -44,10 +44,6 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { const SKIPS_RESERIALIZATION: bool = EsdtTokenPayment::::SKIPS_RESERIALIZATION; type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - EsdtTokenPayment::from_byte_reader(reader).into() - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { EsdtTokenPayment::read_from_payload(payload).into() } diff --git a/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs b/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs index fd7af7c51f..205a219a2c 100644 --- a/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs @@ -1,4 +1,4 @@ -use super::{ManagedVecItem, ManagedVecItemPayload}; +use super::ManagedVecItem; use core::{cmp::Ordering, marker::PhantomData}; pub struct EncodedManagedVecItem @@ -14,9 +14,7 @@ where T: ManagedVecItem, { pub(crate) fn decode(&self) -> T { - T::from_byte_reader(|item_bytes| { - item_bytes.copy_from_slice(self.encoded.payload_slice()); - }) + T::read_from_payload(&self.encoded) } } diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 80d4cc0858..836d6d642c 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -153,17 +153,6 @@ impl EsdtTokenPayment { } } -fn managed_vec_item_from_slice(arr: &[u8], index: &mut usize) -> T -where - T: ManagedVecItem, -{ - ManagedVecItem::from_byte_reader(|bytes| { - let size = T::payload_size(); - bytes.copy_from_slice(&arr[*index..*index + size]); - *index += size; - }) -} - fn managed_vec_item_to_slice(arr: &mut [u8], index: &mut usize, item: T) where T: ManagedVecItem, @@ -189,22 +178,6 @@ impl ManagedVecItem for EsdtTokenPayment { const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut arr: [u8; 16] = [0u8; 16]; - reader(&mut arr[..]); - let mut index = 0; - - let token_identifier = managed_vec_item_from_slice(&arr, &mut index); - let token_nonce = managed_vec_item_from_slice(&arr, &mut index); - let amount = managed_vec_item_from_slice(&arr, &mut index); - - EsdtTokenPayment { - token_identifier, - token_nonce, - amount, - } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; unsafe { diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index 03af276bc9..b29ab033d1 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -203,11 +203,6 @@ where const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - let handle = T::OwnHandle::from_byte_reader(reader); - Self::new_with_handle(handle) - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let handle = use_raw_handle(i32::read_from_payload(payload)); Self::new_with_handle(handle) @@ -218,8 +213,6 @@ where Self::read_from_payload(payload) } - - fn into_byte_writer R>(self, writer: Writer) -> R { ::into_byte_writer(self.handle, writer) } diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index de84d66904..48cbaffc05 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -527,13 +527,17 @@ where return false; } let mut byte_index = 0; + let mut self_payload = T::PAYLOAD::new_buffer(); + let mut other_payload = T::PAYLOAD::new_buffer(); while byte_index < self_len { - let self_item = T::from_byte_reader(|dest_slice| { - let _ = self.buffer.load_slice(byte_index, dest_slice); - }); - let other_item = T::from_byte_reader(|dest_slice| { - let _ = other.buffer.load_slice(byte_index, dest_slice); - }); + let _ = self + .buffer + .load_slice(byte_index, self_payload.payload_slice_mut()); + let _ = self + .buffer + .load_slice(byte_index, other_payload.payload_slice_mut()); + let self_item = T::read_from_payload(&self_payload); + let other_item = T::read_from_payload(&other_payload); if self_item != other_item { return false; } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index c9b59721f2..60ffc83f5c 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -42,8 +42,6 @@ pub trait ManagedVecItem: 'static { } /// Parses given bytes as a an owned object. - fn from_byte_reader(reader: Reader) -> Self; - fn read_from_payload(payload: &Self::PAYLOAD) -> Self; /// Parses given bytes as a representation of the object, either owned, or a reference. @@ -82,12 +80,6 @@ macro_rules! impl_int { const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut arr: [u8; $payload_size] = [0u8; $payload_size]; - reader(&mut arr[..]); - $ty::from_be_bytes(arr) - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { $ty::from_be_bytes(payload.buffer) } @@ -115,12 +107,6 @@ impl ManagedVecItem for usize { const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut arr: [u8; 4] = [0u8; 4]; - reader(&mut arr[..]); - u32::from_be_bytes(arr) as usize - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { u32::read_from_payload(payload) as usize } @@ -140,10 +126,6 @@ impl ManagedVecItem for bool { const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - u8::from_byte_reader(reader) > 0 - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { u8::read_from_payload(payload) > 0 } @@ -169,19 +151,6 @@ where const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut payload = Self::PAYLOAD::new_buffer(); - let payload_slice = payload.payload_slice_mut(); - reader(payload_slice); - if payload_slice[0] == 0 { - None - } else { - Some(T::from_byte_reader(|bytes| { - bytes.copy_from_slice(&payload_slice[1..]); - })) - } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let (p1, p2) = as ManagedVecItemPayloadAdd< T::PAYLOAD, @@ -219,11 +188,6 @@ macro_rules! impl_managed_type { const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = ManagedRef<'a, M, Self>; - fn from_byte_reader(reader: Reader) -> Self { - let handle = <$ty as ManagedType>::OwnHandle::from_byte_reader(reader); - unsafe { $ty::from_handle(handle) } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let handle = use_raw_handle(i32::read_from_payload(payload)); unsafe { Self::from_handle(handle) } @@ -257,11 +221,6 @@ where const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = ManagedRef<'a, M, Self>; - fn from_byte_reader(reader: Reader) -> Self { - let handle = >::OwnHandle::from_byte_reader(reader); - unsafe { Self::from_handle(handle) } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let handle = use_raw_handle(i32::read_from_payload(payload)); unsafe { Self::from_handle(handle) } @@ -289,11 +248,6 @@ where const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = ManagedRef<'a, M, Self>; - fn from_byte_reader(reader: Reader) -> Self { - let handle = M::ManagedBufferHandle::from_byte_reader(reader); - unsafe { Self::from_handle(handle) } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let handle = use_raw_handle(i32::read_from_payload(payload)); unsafe { Self::from_handle(handle) } @@ -315,12 +269,6 @@ impl ManagedVecItem for EsdtTokenType { const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut arr: [u8; 1] = [0u8; 1]; - reader(&mut arr[..]); - arr[0].into() - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { u8::read_from_payload(payload).into() } @@ -339,10 +287,6 @@ impl ManagedVecItem for EsdtLocalRole { const SKIPS_RESERIALIZATION: bool = false; // TODO: might be ok to be true, but needs testing type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - u16::from_byte_reader(reader).into() - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { u16::read_from_payload(payload).into() } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index 4d336632cf..9b22da64f6 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -50,6 +50,12 @@ pub struct ManagedVecItemPayloadBuffer { pub buffer: [u8; N], } +impl From<[u8; N]> for ManagedVecItemPayloadBuffer { + fn from(value: [u8; N]) -> Self { + ManagedVecItemPayloadBuffer { buffer: value } + } +} + impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { fn new_buffer() -> Self { ManagedVecItemPayloadBuffer { buffer: [0u8; N] } diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index c45d5550c2..028c833168 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -43,29 +43,6 @@ fn generate_skips_reserialization_snippets(fields: &syn::Fields) -> Vec Vec { - match fields { - syn::Fields::Named(fields_named) => fields_named - .named - .iter() - .map(|field| { - let field_ident = &field.ident; - let type_name = &field.ty; - quote! { - #field_ident: multiversx_sc::types::ManagedVecItem::from_byte_reader(|bytes| { - let next_index = index + <#type_name as multiversx_sc::types::ManagedVecItem>::payload_size(); - bytes.copy_from_slice(&payload_slice[index .. next_index]); - index = next_index; - }), - } - }) - .collect(), - _ => { - panic!("ManagedVecItem only supports named fields") - } - } -} - fn generate_read_from_payload_snippets(fields: &syn::Fields) -> Vec { match fields { syn::Fields::Named(fields_named) => fields_named @@ -143,14 +120,6 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut arr: [u8; 1] = [0u8; 1]; - reader(&mut arr[..]); - match arr[0] { - #(#reader_match_arms)* - } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let discriminant = ::read_from_payload(payload); match discriminant { @@ -180,7 +149,6 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token let payload_nested_tuple = generate_payload_nested_tuple(&data_struct.fields); let skips_reserialization_snippets = generate_skips_reserialization_snippets(&data_struct.fields); - let from_byte_reader_snippets = generate_from_byte_reader_snippets(&data_struct.fields); let read_from_payload_snippets = generate_read_from_payload_snippets(&data_struct.fields); let to_byte_writer_snippets = generate_to_byte_writer_snippets(&data_struct.fields); @@ -192,16 +160,6 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token const SKIPS_RESERIALIZATION: bool = #(#skips_reserialization_snippets)&&*; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - #payload_buffer_snippet - reader(payload_slice); - let mut index = 0; - - #name { - #(#from_byte_reader_snippets)* - } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 8193c36331..3a21758e6a 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -83,10 +83,6 @@ impl ManagedVecItem for DebugHandle { type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - use_raw_handle(RawHandle::from_byte_reader(reader)) - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { use_raw_handle(RawHandle::read_from_payload(payload)) } diff --git a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs index 6efd920acc..9cbf9ec1b9 100644 --- a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs @@ -65,14 +65,8 @@ fn managed_struct_from_bytes_reader() { let arr: [u8; 8] = [0xff, 0xff, 0xff, handle_bytes[3], 0x00, 0x01, 0x23, 0x45]; let struct_from_bytes = - as multiversx_sc::types::ManagedVecItem>::from_byte_reader( - |bytes| { - bytes.copy_from_slice( - &arr - [0 - .. as multiversx_sc::types::ManagedVecItem>::payload_size()], - ); - }, + as multiversx_sc::types::ManagedVecItem>::read_from_payload( + &arr.into() ); assert_eq!(s, struct_from_bytes); } diff --git a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs index 1018747da3..84dfd54e32 100644 --- a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs @@ -93,14 +93,8 @@ fn struct_from_bytes_reader() { ]; let struct_from_bytes = - as multiversx_sc::types::ManagedVecItem>::from_byte_reader( - |bytes| { - bytes.copy_from_slice( - &arr - [0 - .. as multiversx_sc::types::ManagedVecItem>::payload_size()], - ); - }, + as multiversx_sc::types::ManagedVecItem>::read_from_payload( + &arr.into() ); assert_eq!(s, struct_from_bytes); diff --git a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs index 46dcceed33..11719b6872 100644 --- a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs +++ b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs @@ -39,9 +39,6 @@ fn enum_to_bytes_writer() { #[test] fn enum_from_bytes_reader() { let enum_from_bytes = - ::from_byte_reader(|bytes| { - assert_eq!(bytes.len(), 1); - bytes[0] = 1; - }); + ::read_from_payload(&[1u8].into()); assert_eq!(enum_from_bytes, SimpleEnum::Variant2); } diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs index e55e6d9140..49b43b8711 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs @@ -94,10 +94,6 @@ fn struct_1_from_bytes_reader() { ]; let struct_from_bytes = - ::from_byte_reader(|bytes| { - bytes.copy_from_slice( - &arr[0..::payload_size()], - ); - }); + ::read_from_payload(&arr.into()); assert_eq!(s, struct_from_bytes); } diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs index 50bea73aac..f188f1f64d 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs @@ -67,7 +67,7 @@ fn struct_2_from_bytes_reader() { }; #[rustfmt::skip] - let payload = &[ + let payload = [ /* u_8 */ 0x01, /* u_16 */ 0x00, 0x02, /* u_32 */ 0x00, 0x00, 0x00, 0x03, @@ -78,8 +78,6 @@ fn struct_2_from_bytes_reader() { ]; let struct_from_bytes = - ::from_byte_reader(|bytes| { - bytes.copy_from_slice(&payload[..]); - }); + ::read_from_payload(&payload.into()); assert_eq!(expected_struct, struct_from_bytes); } From 1db9f8e15963ea864e3fb35eb02d32222d00a947 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 02:42:39 +0200 Subject: [PATCH 029/133] clippy fix --- framework/base/src/types/managed/wrapped/managed_vec_item.rs | 5 +++++ .../src/types/managed/wrapped/managed_vec_item_payload.rs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 60ffc83f5c..a920cafadb 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -63,6 +63,11 @@ pub trait ManagedVecItem: 'static { fn into_byte_writer R>(self, writer: Writer) -> R; } +/// Used by the ManagedVecItem derive. +/// +/// ## Safety +/// +/// Only works correctly if the given index is correct, otherwise undefined behavior is possible. pub unsafe fn managed_vec_item_read_from_payload_index(payload: &P, index: &mut usize) -> T where T: ManagedVecItem, diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index 9b22da64f6..f8ba1b17cc 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -14,6 +14,11 @@ pub trait ManagedVecItemPayload { fn payload_slice_mut(&mut self) -> &mut [u8]; + /// Takes a sub-payload item. + /// + /// ## Safety + /// + /// Only works correctly if the given index is correct, otherwise undefined behavior is possible. unsafe fn slice_unchecked(&self, index: usize) -> &S; } From 91011d075534db269ffedfd72bfa3fe43507f27f Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 03:42:01 +0200 Subject: [PATCH 030/133] ManagedVecItem payload refactor - eq fix --- framework/base/src/types/managed/wrapped/managed_vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 48cbaffc05..36d965f55b 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -533,7 +533,7 @@ where let _ = self .buffer .load_slice(byte_index, self_payload.payload_slice_mut()); - let _ = self + let _ = other .buffer .load_slice(byte_index, other_payload.payload_slice_mut()); let self_item = T::read_from_payload(&self_payload); From a886acceb3271302483d1036ad69b083eee81fe9 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 03:56:50 +0200 Subject: [PATCH 031/133] ManagedVecItem payload refactor - save_to_payload impl --- .../esdt_token_payment_multi_value.rs | 4 ++ .../managed/wrapped/esdt_token_payment.rs | 15 ++++- .../types/managed/wrapped/managed_option.rs | 5 ++ .../src/types/managed/wrapped/managed_vec.rs | 4 +- .../types/managed/wrapped/managed_vec_item.rs | 67 ++++++++++++++++++- .../wrapped/managed_vec_item_payload.rs | 54 +++++++++++++++ .../base/src/types/managed/wrapped/mod.rs | 5 +- .../derive/src/managed_vec_item_derive.rs | 33 +++++++++ .../src/api/impl_vh/debug_handle_vh.rs | 4 ++ .../derive_managed_vec_item_biguint_test.rs | 19 +++--- ...anaged_vec_item_esdt_token_payment_test.rs | 19 +++--- .../derive_managed_vec_item_simple_enum.rs | 17 +++-- .../derive_managed_vec_item_struct_1_test.rs | 20 +++--- .../derive_managed_vec_item_struct_2_test.rs | 8 ++- 14 files changed, 225 insertions(+), 49 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 7479df9381..1fd9c5ef2b 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -57,6 +57,10 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { fn into_byte_writer R>(self, writer: Writer) -> R { self.obj.into_byte_writer(writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.obj.save_to_payload(payload); + } } impl TopEncodeMulti for EsdtTokenPaymentMultiValue diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 836d6d642c..435a6e223e 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -13,7 +13,10 @@ use crate::{ derive::type_abi, }; -use super::{managed_vec_item_read_from_payload_index, ManagedVec, ManagedVecItemPayloadBuffer}; +use super::{ + managed_vec_item_read_from_payload_index, managed_vec_item_save_to_payload_index, ManagedVec, + ManagedVecItemPayloadBuffer, +}; #[type_abi] #[derive(TopEncode, NestedEncode, Clone, PartialEq, Eq, Debug)] @@ -204,6 +207,16 @@ impl ManagedVecItem for EsdtTokenPayment { writer(&arr[..]) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let mut index = 0; + + unsafe { + managed_vec_item_save_to_payload_index(self.token_identifier, payload, &mut index); + managed_vec_item_save_to_payload_index(self.token_nonce, payload, &mut index); + managed_vec_item_save_to_payload_index(self.amount, payload, &mut index); + } + } } /// The version of `EsdtTokenPayment` that contains referrences instead of owned fields. diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index b29ab033d1..9616696469 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -2,6 +2,7 @@ use core::marker::PhantomData; use crate::{ abi::TypeAbiFrom, + api::HandleConstraints, codec::{ DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, @@ -216,6 +217,10 @@ where fn into_byte_writer R>(self, writer: Writer) -> R { ::into_byte_writer(self.handle, writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.handle.get_raw_handle().save_to_payload(payload); + } } impl TopEncode for ManagedOption diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 36d965f55b..762f2757f6 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -527,12 +527,12 @@ where return false; } let mut byte_index = 0; - let mut self_payload = T::PAYLOAD::new_buffer(); - let mut other_payload = T::PAYLOAD::new_buffer(); while byte_index < self_len { + let mut self_payload = T::PAYLOAD::new_buffer(); let _ = self .buffer .load_slice(byte_index, self_payload.payload_slice_mut()); + let mut other_payload = T::PAYLOAD::new_buffer(); let _ = other .buffer .load_slice(byte_index, other_payload.payload_slice_mut()); diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index a920cafadb..bd4b311ca2 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -3,7 +3,7 @@ use core::borrow::Borrow; use multiversx_chain_core::types::{EsdtLocalRole, EsdtTokenType}; use crate::{ - api::{use_raw_handle, ManagedTypeApi}, + api::{use_raw_handle, HandleConstraints, ManagedTypeApi}, types::{ BigInt, BigUint, EllipticCurve, ManagedAddress, ManagedBuffer, ManagedByteArray, ManagedRef, ManagedType, ManagedVec, TokenIdentifier, @@ -61,6 +61,8 @@ pub trait ManagedVecItem: 'static { /// /// Note that a destructor should not be called at this moment, since the ManagedVec will take ownership of the item. fn into_byte_writer R>(self, writer: Writer) -> R; + + fn save_to_payload(self, payload: &mut Self::PAYLOAD); } /// Used by the ManagedVecItem derive. @@ -78,6 +80,23 @@ where value } +/// Used by the ManagedVecItem derive. +/// +/// ## Safety +/// +/// Only works correctly if the given index is correct, otherwise undefined behavior is possible. +pub unsafe fn managed_vec_item_save_to_payload_index( + item: T, + payload: &mut P, + index: &mut usize, +) where + T: ManagedVecItem, + P: ManagedVecItemPayload, +{ + item.save_to_payload(payload.slice_unchecked_mut(*index)); + *index += T::PAYLOAD::payload_size(); +} + macro_rules! impl_int { ($ty:ident, $payload_size:expr) => { impl ManagedVecItem for $ty { @@ -97,6 +116,10 @@ macro_rules! impl_int { let bytes = self.to_be_bytes(); writer(&bytes) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + payload.buffer = self.to_be_bytes(); + } } }; } @@ -124,6 +147,10 @@ impl ManagedVecItem for usize { let bytes = (self as u32).to_be_bytes(); writer(&bytes) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + (self as u32).save_to_payload(payload); + } } impl ManagedVecItem for bool { @@ -145,6 +172,10 @@ impl ManagedVecItem for bool { let u8_value = u8::from(self); ::into_byte_writer(u8_value, writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + u8::from(self).save_to_payload(payload); + } } impl ManagedVecItem for Option @@ -184,6 +215,17 @@ where } writer(slice) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let (p1, p2) = as ManagedVecItemPayloadAdd< + T::PAYLOAD, + >>::split_mut_from_add(payload); + + if let Some(t) = self { + 1u8.save_to_payload(p1); + t.save_to_payload(p2); + } + } } macro_rules! impl_managed_type { @@ -207,6 +249,11 @@ macro_rules! impl_managed_type { let handle = unsafe { self.forget_into_handle() }; <$ty as ManagedType>::OwnHandle::into_byte_writer(handle, writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let handle = unsafe { self.forget_into_handle() }; + handle.get_raw_handle().save_to_payload(payload); + } } }; } @@ -242,6 +289,11 @@ where writer, ) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let handle = unsafe { self.forget_into_handle() }; + handle.get_raw_handle().save_to_payload(payload); + } } impl ManagedVecItem for ManagedVec @@ -267,6 +319,11 @@ where let handle = unsafe { self.forget_into_handle() }; ::into_byte_writer(handle, writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let handle = unsafe { self.forget_into_handle() }; + handle.get_raw_handle().save_to_payload(payload); + } } impl ManagedVecItem for EsdtTokenType { @@ -285,6 +342,10 @@ impl ManagedVecItem for EsdtTokenType { fn into_byte_writer R>(self, mut writer: Writer) -> R { writer(&[self.as_u8()]) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.as_u8().save_to_payload(payload); + } } impl ManagedVecItem for EsdtLocalRole { @@ -303,4 +364,8 @@ impl ManagedVecItem for EsdtLocalRole { fn into_byte_writer R>(self, writer: Writer) -> R { ::into_byte_writer(self.as_u16(), writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.as_u16().save_to_payload(payload); + } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index f8ba1b17cc..e13d878a94 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -20,6 +20,13 @@ pub trait ManagedVecItemPayload { /// /// Only works correctly if the given index is correct, otherwise undefined behavior is possible. unsafe fn slice_unchecked(&self, index: usize) -> &S; + + /// Takes a sub-payload item. + /// + /// ## Safety + /// + /// Only works correctly if the given index is correct, otherwise undefined behavior is possible. + unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S; } /// Empty ManagedVecItem. @@ -47,6 +54,10 @@ impl ManagedVecItemPayload for ManagedVecItemEmptyPayload { unsafe fn slice_unchecked(&self, _index: usize) -> &S { unimplemented!() } + + unsafe fn slice_unchecked_mut(&mut self, _index: usize) -> &mut S { + unimplemented!() + } } /// The main ManagedVecItemPayload implementation. Uses an array in its implementation. @@ -82,6 +93,11 @@ impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { let ptr = self.buffer.as_ptr().add(index); &*ptr.cast::() } + + unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S { + let ptr = self.buffer.as_mut_ptr().add(index); + &mut *ptr.cast::() + } } #[repr(transparent)] @@ -125,6 +141,10 @@ where unsafe fn slice_unchecked(&self, index: usize) -> &S { self.buffer.slice_unchecked(index) } + + unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S { + self.buffer.slice_unchecked_mut(index) + } } impl ManagedVecItemPayloadConcat @@ -148,6 +168,12 @@ where fn split_from_add(_payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { todo!() } + + fn split_mut_from_add( + _payload: &mut Self::Output, + ) -> (&mut Self, &mut ManagedVecItemPayloadConcat) { + todo!() + } } pub struct ManagedVecItemPayloadEquiv @@ -182,6 +208,10 @@ where unsafe fn slice_unchecked(&self, index: usize) -> &S { self.equiv.slice_unchecked(index) } + + unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S { + self.equiv.slice_unchecked_mut(index) + } } /// Describes concatantion of smaller payloads into a larger one. @@ -196,6 +226,8 @@ where type Output: ManagedVecItemPayload; fn split_from_add(payload: &Self::Output) -> (&Self, &Rhs); + + fn split_mut_from_add(payload: &mut Self::Output) -> (&mut Self, &mut Rhs); } impl

ManagedVecItemPayloadAdd for P @@ -207,6 +239,12 @@ where fn split_from_add(payload: &Self::Output) -> (&Self, &ManagedVecItemEmptyPayload) { (payload, &ManagedVecItemEmptyPayload) } + + fn split_mut_from_add( + _payload: &mut Self::Output, + ) -> (&mut Self, &mut ManagedVecItemEmptyPayload) { + unimplemented!() + } } /// Replaces a const generic expression. @@ -234,6 +272,22 @@ macro_rules! payload_add { ) } } + + fn split_mut_from_add( + payload: &mut Self::Output, + ) -> ( + &mut ManagedVecItemPayloadBuffer<$dec1>, + &mut ManagedVecItemPayloadBuffer<$dec2>, + ) { + unsafe { + let ptr1 = payload.buffer.as_mut_ptr(); + let ptr2 = ptr1.add($dec1); + ( + &mut *ptr1.cast::>(), + &mut *ptr2.cast::>(), + ) + } + } } }; } diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped/mod.rs index 38d721812e..4ca4ad6d97 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -46,7 +46,10 @@ pub use managed_option::ManagedOption; pub use managed_ref::ManagedRef; pub use managed_ref_mut::ManagedRefMut; pub use managed_vec::ManagedVec; -pub use managed_vec_item::{managed_vec_item_read_from_payload_index, ManagedVecItem}; +pub use managed_vec_item::{ + managed_vec_item_read_from_payload_index, managed_vec_item_save_to_payload_index, + ManagedVecItem, +}; pub use managed_vec_item_nested_tuple::{ ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, }; diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index 028c833168..397d83f55a 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -84,6 +84,24 @@ fn generate_to_byte_writer_snippets(fields: &syn::Fields) -> Vec Vec { + match fields { + syn::Fields::Named(fields_named) => fields_named + .named + .iter() + .map(|field| { + let field_ident = &field.ident; + quote! { + multiversx_sc::types::managed_vec_item_save_to_payload_index(self.#field_ident, payload, &mut index); + } + }) + .collect(), + _ => { + panic!("ManagedVecItem only supports named fields") + } + } +} + fn generate_payload_buffer_snippet() -> proc_macro2::TokenStream { quote! { let mut payload = ::new_buffer(); @@ -138,6 +156,13 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream }; writer(&arr[..]) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let discriminant = match self { + #(#writer_match_arms)* + }; + ::save_to_payload(discriminant, payload); + } } }; gen.into() @@ -151,6 +176,7 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token generate_skips_reserialization_snippets(&data_struct.fields); let read_from_payload_snippets = generate_read_from_payload_snippets(&data_struct.fields); let to_byte_writer_snippets = generate_to_byte_writer_snippets(&data_struct.fields); + let save_to_payload_snippets = generate_save_to_payload_snippets(&data_struct.fields); let payload_buffer_snippet = generate_payload_buffer_snippet(); @@ -183,6 +209,13 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token writer(&payload_slice[..]) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let mut index = 0; + unsafe { + #(#save_to_payload_snippets)* + } + } } }; gen.into() diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 3a21758e6a..2157ab2877 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -94,6 +94,10 @@ impl ManagedVecItem for DebugHandle { fn into_byte_writer R>(self, writer: Writer) -> R { RawHandle::into_byte_writer(self.get_raw_handle(), writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.get_raw_handle().save_to_payload(payload); + } } impl TryStaticCast for DebugHandle {} diff --git a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs index 9cbf9ec1b9..7f0d06be8f 100644 --- a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs @@ -1,7 +1,9 @@ use multiversx_sc::{ api::ManagedTypeApi, - codec, - codec::derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + codec::{ + self, + derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + }, derive::ManagedVecItem, types::{BigUint, ManagedType, ManagedVecItemPayload}, }; @@ -39,20 +41,15 @@ fn managed_struct_to_bytes_writer() { num: 0x12345, }; - let mut payload = as multiversx_sc::types::ManagedVecItem>::PAYLOAD::new_buffer(); - let payload_slice = payload.payload_slice_mut(); - let handle_bytes = s.big_uint.get_handle().to_be_bytes(); let expected = [0xff, 0xff, 0xff, handle_bytes[3], 0x00, 0x01, 0x23, 0x45]; - as multiversx_sc::types::ManagedVecItem>::into_byte_writer( + let mut payload = as multiversx_sc::types::ManagedVecItem>::PAYLOAD::new_buffer(); + as multiversx_sc::types::ManagedVecItem>::save_to_payload( s, - |bytes| { - payload_slice.copy_from_slice(bytes); - - assert_eq!(payload_slice, expected); - }, + &mut payload, ); + assert_eq!(payload.buffer, expected); } #[test] diff --git a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs index 84dfd54e32..c6dea79b94 100644 --- a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs @@ -1,7 +1,9 @@ use multiversx_sc::{ api::ManagedTypeApi, - codec, - codec::derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + codec::{ + self, + derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + }, derive::ManagedVecItem, types::{ BigUint, EsdtTokenPayment, ManagedByteArray, ManagedType, ManagedVecItemPayload, @@ -50,9 +52,6 @@ fn struct_to_bytes_writer() { eth_address_2: ManagedByteArray::new_from_bytes(&[2u8; 20]), }; - let mut payload = as multiversx_sc::types::ManagedVecItem>::PAYLOAD::new_buffer(); - let payload_slice = payload.payload_slice_mut(); - let handle1 = s.token.token_identifier.get_handle().to_be_bytes(); let handle2 = s.token.amount.get_handle().to_be_bytes(); let handle3 = s.eth_address_1.get_handle().to_be_bytes(); @@ -63,14 +62,12 @@ fn struct_to_bytes_writer() { handle3[1], handle3[2], handle3[3], handle4[0], handle4[1], handle4[2], handle4[3], ]; - as multiversx_sc::types::ManagedVecItem>::into_byte_writer( + let mut payload = as multiversx_sc::types::ManagedVecItem>::PAYLOAD::new_buffer(); + as multiversx_sc::types::ManagedVecItem>::save_to_payload( s, - |bytes| { - payload_slice.copy_from_slice(bytes); - - assert_eq!(payload_slice, expected); - }, + &mut payload, ); + assert_eq!(payload.buffer, expected); } #[test] diff --git a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs index 11719b6872..5a41283613 100644 --- a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs +++ b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs @@ -1,7 +1,10 @@ use multiversx_sc::{ - codec, - codec::derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + codec::{ + self, + derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + }, derive::ManagedVecItem, + types::{ManagedVecItemPayload, ManagedVecItemPayloadBuffer}, }; // to test, run the following command in the crate folder: @@ -27,13 +30,13 @@ fn enum_static() { #[test] fn enum_to_bytes_writer() { - ::into_byte_writer( + let mut payload = ManagedVecItemPayloadBuffer::new_buffer(); + ::save_to_payload( SimpleEnum::Variant1, - |bytes| { - assert_eq!(bytes.len(), 1); - assert_eq!(bytes[0], 0); - }, + &mut payload, ); + + assert_eq!(payload.buffer, [0]); } #[test] diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs index 49b43b8711..20746bcb80 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs @@ -65,18 +65,14 @@ fn struct_1_to_bytes_writer() { }; let mut payload = ::PAYLOAD::new_buffer(); - let payload_slice = payload.payload_slice_mut(); - - ::into_byte_writer(s, |bytes| { - payload_slice.copy_from_slice(bytes); - assert_eq!( - payload_slice, - [ - 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x01, - ] - ); - }); + ::save_to_payload(s, &mut payload); + assert_eq!( + payload.buffer, + [ + 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x01, + ] + ); } #[test] diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs index f188f1f64d..641bb04a0b 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs @@ -1,3 +1,5 @@ +use multiversx_sc::types::{ManagedVecItemPayload, ManagedVecItemPayloadBuffer}; + multiversx_sc::derive_imports!(); // to test, run the following command in the crate folder: @@ -49,9 +51,9 @@ fn struct_to_bytes_writer() { /* arr */ 0x61, 0x11, 0x62, 0x22, ]; - ::into_byte_writer(s, |bytes| { - assert_eq!(bytes, &expected_payload[..]); - }); + let mut payload = ManagedVecItemPayloadBuffer::new_buffer(); + ::save_to_payload(s, &mut payload); + assert_eq!(payload.buffer, &expected_payload[..]); } #[test] From 01a849e9a31c8b56f88b5a7d286f8cacb748dd0c Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 10:03:20 +0200 Subject: [PATCH 032/133] ManagedVecItem payload refactor - remove into_byte_writer --- .../esdt_token_payment_multi_value.rs | 5 -- .../managed/wrapped/esdt_token_payment.rs | 22 ------- .../types/managed/wrapped/managed_option.rs | 4 -- .../src/types/managed/wrapped/managed_vec.rs | 16 ++--- .../types/managed/wrapped/managed_vec_item.rs | 60 +------------------ .../derive/src/managed_vec_item_derive.rs | 50 ---------------- .../src/api/impl_vh/debug_handle_vh.rs | 4 -- 7 files changed, 10 insertions(+), 151 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 1fd9c5ef2b..d881b6a995 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -53,11 +53,6 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { Self::read_from_payload(payload) } - #[inline] - fn into_byte_writer R>(self, writer: Writer) -> R { - self.obj.into_byte_writer(writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { self.obj.save_to_payload(payload); } diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 435a6e223e..b676fa42cc 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -156,17 +156,6 @@ impl EsdtTokenPayment { } } -fn managed_vec_item_to_slice(arr: &mut [u8], index: &mut usize, item: T) -where - T: ManagedVecItem, -{ - ManagedVecItem::into_byte_writer(item, |bytes| { - let size = T::payload_size(); - arr[*index..*index + size].copy_from_slice(bytes); - *index += size; - }); -} - impl IntoMultiValue for EsdtTokenPayment { type MultiValue = EsdtTokenPaymentMultiValue; @@ -197,17 +186,6 @@ impl ManagedVecItem for EsdtTokenPayment { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let mut arr: [u8; 16] = [0u8; 16]; - let mut index = 0; - - managed_vec_item_to_slice(&mut arr, &mut index, self.token_identifier); - managed_vec_item_to_slice(&mut arr, &mut index, self.token_nonce); - managed_vec_item_to_slice(&mut arr, &mut index, self.amount); - - writer(&arr[..]) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let mut index = 0; diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index 9616696469..c7ee9371b9 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -214,10 +214,6 @@ where Self::read_from_payload(payload) } - fn into_byte_writer R>(self, writer: Writer) -> R { - ::into_byte_writer(self.handle, writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { self.handle.get_raw_handle().save_to_payload(payload); } diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 762f2757f6..4bbf073088 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -201,7 +201,9 @@ where pub fn set(&mut self, index: usize, item: T) -> Result<(), InvalidSliceError> { let byte_index = index * T::payload_size(); - item.into_byte_writer(|slice| self.buffer.set_slice(byte_index, slice)) + let mut payload = T::PAYLOAD::new_buffer(); + item.save_to_payload(&mut payload); + self.buffer.set_slice(byte_index, payload.payload_slice()) } /// Returns a new `ManagedVec`, containing the [start_index, end_index) range of elements. @@ -214,9 +216,9 @@ where } pub fn push(&mut self, item: T) { - item.into_byte_writer(|bytes| { - self.buffer.append_bytes(bytes); - }); + let mut payload = T::PAYLOAD::new_buffer(); + item.save_to_payload(&mut payload); + self.buffer.append_bytes(payload.payload_slice()); } pub fn remove(&mut self, index: usize) { @@ -260,9 +262,9 @@ where } pub fn overwrite_with_single_item(&mut self, item: T) { - item.into_byte_writer(|bytes| { - self.buffer.overwrite(bytes); - }); + let mut payload = T::PAYLOAD::new_buffer(); + item.save_to_payload(&mut payload); + self.buffer.overwrite(payload.payload_slice()); } /// Appends all the contents of another managed vec at the end of the current one. diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index bd4b311ca2..0752796145 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -53,15 +53,9 @@ pub trait ManagedVecItem: 'static { /// Converts the object into bytes. /// - /// The output is processed by the `writer` lambda. - /// The writer is provided by the caller. - /// The callee will use it to pass on the bytes. - /// /// The method is used when instering (push, overwrite) into a ManagedVec. /// /// Note that a destructor should not be called at this moment, since the ManagedVec will take ownership of the item. - fn into_byte_writer R>(self, writer: Writer) -> R; - fn save_to_payload(self, payload: &mut Self::PAYLOAD); } @@ -112,11 +106,6 @@ macro_rules! impl_int { $ty::from_be_bytes(payload.buffer) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let bytes = self.to_be_bytes(); - writer(&bytes) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { payload.buffer = self.to_be_bytes(); } @@ -143,11 +132,6 @@ impl ManagedVecItem for usize { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let bytes = (self as u32).to_be_bytes(); - writer(&bytes) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { (self as u32).save_to_payload(payload); } @@ -166,14 +150,9 @@ impl ManagedVecItem for bool { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, writer: Writer) -> R { + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { // true -> 1u8 // false -> 0u8 - let u8_value = u8::from(self); - ::into_byte_writer(u8_value, writer) - } - - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { u8::from(self).save_to_payload(payload); } } @@ -204,18 +183,6 @@ where Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let mut payload = Self::PAYLOAD::new_buffer(); - let slice = payload.payload_slice_mut(); - if let Some(t) = self { - slice[0] = 1; - T::into_byte_writer(t, |bytes| { - slice[1..].copy_from_slice(bytes); - }); - } - writer(slice) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let (p1, p2) = as ManagedVecItemPayloadAdd< T::PAYLOAD, @@ -245,11 +212,6 @@ macro_rules! impl_managed_type { ManagedRef::wrap_handle(handle) } - fn into_byte_writer R>(self, writer: Writer) -> R { - let handle = unsafe { self.forget_into_handle() }; - <$ty as ManagedType>::OwnHandle::into_byte_writer(handle, writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let handle = unsafe { self.forget_into_handle() }; handle.get_raw_handle().save_to_payload(payload); @@ -283,13 +245,6 @@ where ManagedRef::wrap_handle(handle) } - fn into_byte_writer R>(self, writer: Writer) -> R { - <>::OwnHandle as ManagedVecItem>::into_byte_writer( - self.get_handle(), - writer, - ) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let handle = unsafe { self.forget_into_handle() }; handle.get_raw_handle().save_to_payload(payload); @@ -315,11 +270,6 @@ where ManagedRef::wrap_handle(handle) } - fn into_byte_writer R>(self, writer: Writer) -> R { - let handle = unsafe { self.forget_into_handle() }; - ::into_byte_writer(handle, writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let handle = unsafe { self.forget_into_handle() }; handle.get_raw_handle().save_to_payload(payload); @@ -339,10 +289,6 @@ impl ManagedVecItem for EsdtTokenType { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - writer(&[self.as_u8()]) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { self.as_u8().save_to_payload(payload); } @@ -361,10 +307,6 @@ impl ManagedVecItem for EsdtLocalRole { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, writer: Writer) -> R { - ::into_byte_writer(self.as_u16(), writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { self.as_u16().save_to_payload(payload); } diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index 397d83f55a..1531b00610 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -61,29 +61,6 @@ fn generate_read_from_payload_snippets(fields: &syn::Fields) -> Vec Vec { - match fields { - syn::Fields::Named(fields_named) => fields_named - .named - .iter() - .map(|field| { - let field_ident = &field.ident; - let type_name = &field.ty; - quote! { - multiversx_sc::types::ManagedVecItem::into_byte_writer(self.#field_ident, |bytes| { - let next_index = index + <#type_name as multiversx_sc::types::ManagedVecItem>::payload_size(); - payload_slice[index .. next_index].copy_from_slice(bytes); - index = next_index; - }); - } - }) - .collect(), - _ => { - panic!("ManagedVecItem only supports named fields") - } - } -} - fn generate_save_to_payload_snippets(fields: &syn::Fields) -> Vec { match fields { syn::Fields::Named(fields_named) => fields_named @@ -102,13 +79,6 @@ fn generate_save_to_payload_snippets(fields: &syn::Fields) -> Vec proc_macro2::TokenStream { - quote! { - let mut payload = ::new_buffer(); - let payload_slice = multiversx_sc::types::ManagedVecItemPayload::payload_slice_mut(&mut payload); - } -} - fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; let (impl_generics, ty_generics, where_clause) = &ast.generics.split_for_impl(); @@ -149,14 +119,6 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let mut arr: [u8; 1] = [0u8; 1]; - arr[0] = match self { - #(#writer_match_arms)* - }; - writer(&arr[..]) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let discriminant = match self { #(#writer_match_arms)* @@ -175,11 +137,8 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token let skips_reserialization_snippets = generate_skips_reserialization_snippets(&data_struct.fields); let read_from_payload_snippets = generate_read_from_payload_snippets(&data_struct.fields); - let to_byte_writer_snippets = generate_to_byte_writer_snippets(&data_struct.fields); let save_to_payload_snippets = generate_save_to_payload_snippets(&data_struct.fields); - let payload_buffer_snippet = generate_payload_buffer_snippet(); - let gen = quote! { impl #impl_generics multiversx_sc::types::ManagedVecItem for #name #ty_generics #where_clause { type PAYLOAD = <#payload_nested_tuple as multiversx_sc::types::ManagedVecItemNestedTuple>::PAYLOAD; @@ -201,15 +160,6 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - #payload_buffer_snippet - let mut index = 0; - - #(#to_byte_writer_snippets)* - - writer(&payload_slice[..]) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let mut index = 0; unsafe { diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 2157ab2877..64fcd15fa9 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -91,10 +91,6 @@ impl ManagedVecItem for DebugHandle { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, writer: Writer) -> R { - RawHandle::into_byte_writer(self.get_raw_handle(), writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { self.get_raw_handle().save_to_payload(payload); } From 2afe44488b6ac3338c8c050d0fdf61b4d7d20a73 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 10:26:22 +0200 Subject: [PATCH 033/133] ManagedVecItem payload refactor - cleanup --- .../wrapped/managed_vec_item_nested_tuple.rs | 79 ------------ .../wrapped/managed_vec_item_payload.rs | 118 ------------------ .../base/src/types/managed/wrapped/mod.rs | 4 +- 3 files changed, 1 insertion(+), 200 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs index 11a7055a40..3a25bf4993 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs @@ -5,33 +5,11 @@ use super::{ /// Syntactic sugar, that allows us to more easily represent composite payloads as nested tuples. pub trait ManagedVecItemNestedTuple { type PAYLOAD: ManagedVecItemPayload; - type Split1: ManagedVecItemPayload; - type Split2: ManagedVecItemPayload; - - fn split_payload(payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2); -} - -pub trait ManagedVecItemNestedTupleSplit<'a>: ManagedVecItemNestedTuple { - type S; - - fn split_all(payload: &'a Self::PAYLOAD) -> Self::S; } /// End of the list. impl ManagedVecItemNestedTuple for () { type PAYLOAD = ManagedVecItemEmptyPayload; - type Split1 = ManagedVecItemEmptyPayload; - type Split2 = ManagedVecItemEmptyPayload; - - fn split_payload(_payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2) { - (&ManagedVecItemEmptyPayload, &ManagedVecItemEmptyPayload) - } -} - -impl<'a> ManagedVecItemNestedTupleSplit<'a> for () { - type S = (); - - fn split_all(_payload: &'a Self::PAYLOAD) -> Self::S {} } impl ManagedVecItemNestedTuple for (Head, Tail) @@ -41,51 +19,10 @@ where Head::PAYLOAD: ManagedVecItemPayloadAdd, { type PAYLOAD = >::Output; - type Split1 = ::PAYLOAD; - type Split2 = ::PAYLOAD; - - fn split_payload(payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2) { - Head::PAYLOAD::split_from_add(payload) - } } -impl<'a, Head, Tail> ManagedVecItemNestedTupleSplit<'a> for (Head, Tail) -where - Head: ManagedVecItem, - Tail: ManagedVecItemNestedTupleSplit<'a>, - Head::PAYLOAD: ManagedVecItemPayloadAdd, - Tail::PAYLOAD: 'a, -{ - type S = (&'a Head::PAYLOAD, Tail::S); - - fn split_all(payload: &'a Self::PAYLOAD) -> Self::S { - let (hp, tp) = Head::PAYLOAD::split_from_add(payload); - (hp, Tail::split_all(tp)) - } -} - -// pub fn split_payload( -// payload: &<(Head, Tail) as ManagedVecItemNestedTuple>::PAYLOAD, -// ) -> (&Head::PAYLOAD, &Tail::PAYLOAD) -// where -// Head: ManagedVecItem, -// Tail: ManagedVecItemNestedTuple, -// Head::PAYLOAD: ManagedVecItemPayloadAdd, -// // (Head, Tail): ManagedVecItemNestedTuple, -// { -// >::split_from_add(payload) -// // <(Head, Tail) as ManagedVecItemNestedTuple>::PAYLOAD as -// // unsafe { -// // let ptr1 = payload.buffer.as_ptr(); -// // let ptr2 = ptr1.offset($dec1 as isize); -// // (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) -// // } -// } - #[cfg(test)] pub mod tests { - use crate::types::ManagedVecItemPayloadBuffer; - use super::*; #[test] @@ -100,20 +37,4 @@ pub mod tests { fn assert_payload_size(expected_size: usize) { assert_eq!(N::PAYLOAD::payload_size(), expected_size); } - - #[test] - fn split_all_test() { - let p = ManagedVecItemPayloadBuffer::new_buffer(); - let (_p1, (_p2, ())) = <(u16, (u32, ()))>::split_all(&p); - } - - // fn split_all_t() - // where - // T: ManagedVecItem, - // ManagedVecItemPayloadBuffer<1>: ManagedVecItemPayloadAdd, - // (u16, (T, ())): ManagedVecItemNestedTuple, - // { - // let p = ManagedVecItemPayloadBuffer::new_buffer(); - // let (p1, (p2, ())) = <(u16, (T, ()))>::split_all(&p); - // } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index e13d878a94..a3a9c58475 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -1,7 +1,3 @@ -use core::marker::PhantomData; - -use super::ManagedVecItem; - /// Describes the binary represetnation of a ManagedVecItem. /// /// It is always an array that can be allocated directly on stack. @@ -100,120 +96,6 @@ impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { } } -#[repr(transparent)] -pub struct ManagedVecItemPayloadConcat -where - P1: ManagedVecItemPayload, - P2: ManagedVecItemPayload, - P1: ManagedVecItemPayloadAdd, -{ - _phantom_1: PhantomData, - _phantom_2: PhantomData, - buffer: >::Output, -} - -impl ManagedVecItemPayload for ManagedVecItemPayloadConcat -where - P1: ManagedVecItemPayload, - P2: ManagedVecItemPayload, - P1: ManagedVecItemPayloadAdd, -{ - fn new_buffer() -> Self { - ManagedVecItemPayloadConcat { - _phantom_1: PhantomData, - _phantom_2: PhantomData, - buffer: ManagedVecItemPayload::new_buffer(), - } - } - - fn payload_size() -> usize { - >::Output::payload_size() - } - - fn payload_slice(&self) -> &[u8] { - self.buffer.payload_slice() - } - - fn payload_slice_mut(&mut self) -> &mut [u8] { - self.buffer.payload_slice_mut() - } - - unsafe fn slice_unchecked(&self, index: usize) -> &S { - self.buffer.slice_unchecked(index) - } - - unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S { - self.buffer.slice_unchecked_mut(index) - } -} - -impl ManagedVecItemPayloadConcat -where - P1: ManagedVecItemPayload, - P2: ManagedVecItemPayload, - P1: ManagedVecItemPayloadAdd, -{ -} - -impl ManagedVecItemPayloadAdd> for P0 -where - P0: ManagedVecItemPayload, - P1: ManagedVecItemPayload, - P2: ManagedVecItemPayload, - P1: ManagedVecItemPayloadAdd, - P0: ManagedVecItemPayloadAdd<>::Output>, -{ - type Output = ManagedVecItemPayloadConcat>; - - fn split_from_add(_payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { - todo!() - } - - fn split_mut_from_add( - _payload: &mut Self::Output, - ) -> (&mut Self, &mut ManagedVecItemPayloadConcat) { - todo!() - } -} - -pub struct ManagedVecItemPayloadEquiv -where - T: ManagedVecItem, -{ - equiv: T::PAYLOAD, -} - -impl ManagedVecItemPayload for ManagedVecItemPayloadEquiv -where - T: ManagedVecItem, -{ - fn new_buffer() -> Self { - ManagedVecItemPayloadEquiv { - equiv: ManagedVecItemPayload::new_buffer(), - } - } - - fn payload_size() -> usize { - T::PAYLOAD::payload_size() - } - - fn payload_slice(&self) -> &[u8] { - self.equiv.payload_slice() - } - - fn payload_slice_mut(&mut self) -> &mut [u8] { - self.equiv.payload_slice_mut() - } - - unsafe fn slice_unchecked(&self, index: usize) -> &S { - self.equiv.slice_unchecked(index) - } - - unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S { - self.equiv.slice_unchecked_mut(index) - } -} - /// Describes concatantion of smaller payloads into a larger one. /// /// There is no runtime implementation, just a type-level addition. diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped/mod.rs index 4ca4ad6d97..5086c3bc26 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -50,9 +50,7 @@ pub use managed_vec_item::{ managed_vec_item_read_from_payload_index, managed_vec_item_save_to_payload_index, ManagedVecItem, }; -pub use managed_vec_item_nested_tuple::{ - ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, -}; +pub use managed_vec_item_nested_tuple::ManagedVecItemNestedTuple; pub use managed_vec_item_payload::*; pub use managed_vec_owned_iter::ManagedVecOwnedIterator; pub use managed_vec_ref::ManagedVecRef; From cb60d95f77f66830b9220be7a6d07e3285e23f84 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 14:45:41 +0200 Subject: [PATCH 034/133] ManagedVecItem payload refactor - fix after merge --- .../multi_value_managed_vec_counted.rs | 14 +- .../types/managed/wrapped/managed_vec_item.rs | 127 ++++++------------ 2 files changed, 48 insertions(+), 93 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs b/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs index a46016e69a..0cb695e0d5 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs @@ -98,18 +98,16 @@ where const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - Self::from(ManagedVec::::from_byte_reader(reader)) + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + Self::from(ManagedVec::::read_from_payload(payload)) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) } - fn into_byte_writer R>(self, writer: Writer) -> R { - self.contents.into_byte_writer(writer) + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.contents.save_to_payload(payload); } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 94a4c6cd1f..65ed262a41 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -11,7 +11,10 @@ use crate::{ }, }; -use super::{ManagedVecItemPayload, ManagedVecItemPayloadAdd, ManagedVecItemPayloadBuffer}; +use super::{ + ManagedVecItemNestedTuple, ManagedVecItemPayload, ManagedVecItemPayloadAdd, + ManagedVecItemPayloadBuffer, +}; /// Types that implement this trait can be items inside a `ManagedVec`. /// All these types need a payload, i.e a representation that gets stored @@ -323,49 +326,30 @@ where const SKIPS_RESERIALIZATION: bool = T1::SKIPS_RESERIALIZATION && T2::SKIPS_RESERIALIZATION; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut payload = ::new_buffer(); - let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload); - reader(payload_slice); + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; - - ( - T1::from_byte_reader(|bytes| { - let next_index = index + T1::payload_size(); - bytes.copy_from_slice(&payload_slice[index..next_index]); - index = next_index; - }), - T2::from_byte_reader(|bytes| { - let next_index = index + T2::payload_size(); - bytes.copy_from_slice(&payload_slice[index..next_index]); - index = next_index; - }), - ) - .into() + unsafe { + ( + managed_vec_item_read_from_payload_index(payload, &mut index), + managed_vec_item_read_from_payload_index(payload, &mut index), + ) + .into() + } } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: tuple of refs + Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let mut payload = Self::PAYLOAD::new_buffer(); - let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload); + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let tuple = self.into_tuple(); let mut index = 0; - let (t1, t2) = self.into_tuple(); - T1::into_byte_writer(t1, |bytes| { - let next_index = index + T1::payload_size(); - payload_slice[index..next_index].copy_from_slice(bytes); - index = next_index; - }); - T2::into_byte_writer(t2, |bytes| { - let next_index = index + T2::payload_size(); - payload_slice[index..next_index].copy_from_slice(bytes); - index = next_index; - }); - writer(payload_slice) + + unsafe { + managed_vec_item_save_to_payload_index(tuple.0, payload, &mut index); + managed_vec_item_save_to_payload_index(tuple.1, payload, &mut index); + } } } @@ -380,58 +364,31 @@ where const SKIPS_RESERIALIZATION: bool = T1::SKIPS_RESERIALIZATION && T2::SKIPS_RESERIALIZATION; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut payload = ::new_buffer(); - let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload); - reader(payload_slice); + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; - - ( - T1::from_byte_reader(|bytes| { - let next_index = index + T1::payload_size(); - bytes.copy_from_slice(&payload_slice[index..next_index]); - index = next_index; - }), - T2::from_byte_reader(|bytes| { - let next_index = index + T2::payload_size(); - bytes.copy_from_slice(&payload_slice[index..next_index]); - index = next_index; - }), - T3::from_byte_reader(|bytes| { - let next_index = index + T3::payload_size(); - bytes.copy_from_slice(&payload_slice[index..next_index]); - index = next_index; - }), - ) - .into() + unsafe { + ( + managed_vec_item_read_from_payload_index(payload, &mut index), + managed_vec_item_read_from_payload_index(payload, &mut index), + managed_vec_item_read_from_payload_index(payload, &mut index), + ) + .into() + } } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: tuple of refs + Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let mut payload = Self::PAYLOAD::new_buffer(); - let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload); + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let tuple = self.into_tuple(); let mut index = 0; - let (t1, t2, t3) = self.into_tuple(); - T1::into_byte_writer(t1, |bytes| { - let next_index = index + T1::payload_size(); - payload_slice[index..next_index].copy_from_slice(bytes); - index = next_index; - }); - T2::into_byte_writer(t2, |bytes| { - let next_index = index + T2::payload_size(); - payload_slice[index..next_index].copy_from_slice(bytes); - index = next_index; - }); - T3::into_byte_writer(t3, |bytes| { - let next_index = index + T2::payload_size(); - payload_slice[index..next_index].copy_from_slice(bytes); - index = next_index; - }); - writer(payload_slice) + + unsafe { + managed_vec_item_save_to_payload_index(tuple.0, payload, &mut index); + managed_vec_item_save_to_payload_index(tuple.1, payload, &mut index); + managed_vec_item_save_to_payload_index(tuple.2, payload, &mut index); + } } } From 567b8f1cdc22749d85d48d1e983ce6428816e652 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Wed, 27 Nov 2024 14:53:52 +0200 Subject: [PATCH 035/133] clippy fix --- chain/vm/src/tx_execution/exec_general_tx.rs | 21 ++++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/chain/vm/src/tx_execution/exec_general_tx.rs b/chain/vm/src/tx_execution/exec_general_tx.rs index abf4d4344e..53ca60bc30 100644 --- a/chain/vm/src/tx_execution/exec_general_tx.rs +++ b/chain/vm/src/tx_execution/exec_general_tx.rs @@ -52,17 +52,16 @@ pub(crate) fn create_transfer_value_log(tx_input: &TxInput, call_type: CallType) let mut data = vec![call_type.to_log_bytes(), tx_input.func_name.to_bytes()]; data.append(&mut tx_input.args.clone()); - if tx_input.esdt_values.is_empty() { - if !tx_input.callback_payments.egld_value.is_zero() - && tx_input.call_type == CallType::AsyncCallback - { - return TxLog { - address: tx_input.from.clone(), - endpoint: "transferValueOnly".into(), - topics: vec![b"".to_vec(), tx_input.to.to_vec()], - data, - }; - } + if tx_input.esdt_values.is_empty() + && !tx_input.callback_payments.egld_value.is_zero() + && tx_input.call_type == CallType::AsyncCallback + { + return TxLog { + address: tx_input.from.clone(), + endpoint: "transferValueOnly".into(), + topics: vec![b"".to_vec(), tx_input.to.to_vec()], + data, + }; } let egld_value = if tx_input.call_type == CallType::AsyncCallback { From dcaad2493f2fabf401d3c7e3c60d2f5367da17eb Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Wed, 27 Nov 2024 13:57:40 +0100 Subject: [PATCH 036/133] interactor tests run sequentially, test fix --- .../examples/adder/interactor/Cargo.toml | 1 + .../examples/adder/interactor/set_state.json | 70 +++++++++---------- .../tests/basic_interactor_cs_test.rs | 10 ++- 3 files changed, 45 insertions(+), 36 deletions(-) diff --git a/contracts/examples/adder/interactor/Cargo.toml b/contracts/examples/adder/interactor/Cargo.toml index 30db735223..c6b37c739a 100644 --- a/contracts/examples/adder/interactor/Cargo.toml +++ b/contracts/examples/adder/interactor/Cargo.toml @@ -24,6 +24,7 @@ clap = { version = "4.4.7", features = ["derive"] } serde = { version = "1.0", features = ["derive"] } toml = "0.8.6" tokio = { version = "1.24" } +serial_test = { version = "3.2.0" } [features] chain-simulator-tests = [] diff --git a/contracts/examples/adder/interactor/set_state.json b/contracts/examples/adder/interactor/set_state.json index a5364326ab..a5115b7781 100644 --- a/contracts/examples/adder/interactor/set_state.json +++ b/contracts/examples/adder/interactor/set_state.json @@ -4,47 +4,47 @@ "nonce": 5947, "balance": "491982310359999986", "keys": { + "454c524f4e44657364745453542d363437383930": "1209004563918244f40000", + "454c524f4e446e6f6e636550544d2d353336666162": "01", "454c524f4e446573647450544d2d35333666616201": "08021202000122ef0108011212546573742d5061696e742d486172766573741a20e32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed6020c4132a2e516d57564239575362674b52655a64615a434344766b454b70705a6b4d696d397563736e7857565041414c6a4374324368747470733a2f2f697066732e696f2f697066732f516d57564239575362674b52655a64615a434344766b454b70705a6b4d696d397563736e7857565041414c6a43743a3d746167733a3b6d657461646174613a516d52635039346b5872357a5a6a52477669376d4a36756e374c7078556859565234523452706963787a67596b74", - "454c524f4e44657364745453542d643964336136": "1209004563918244f40000", - "454c524f4e44657364745745474c442d613238633539": "120900389351ce08f09e12", - "454c524f4e44657364745453542d633636666535": "1209004563918244f40000", - "454c524f4e44657364745453542d623130616461": "1209004563918244f40000", - "454c524f4e4465736474475245454e2d306531363163": "120b00152d02c7e14af67fffdc", - "454c524f4e44657364745453542d656338383735": "12020064", - "454c524f4e44657364744c5453542d376266336431": "1209000de0b6b3a763fc19", - "454c524f4e44657364745453542d343265356138": "1209004563918244f40000", "454c524f4e44726f6c656573647450544d2d353336666162": "0a1145534454526f6c654e46544372656174650a0f45534454526f6c654e46544275726e", - "454c524f4e44657364745453542d393836646663": "12020064", - "454c524f4e44657364745453542d323833633361": "12020064", - "454c524f4e4465736474424358535542542d33393264366172": "080112020001", + "454c524f4e44657364745453542d633565303835": "1209004563918244f40000", + "454c524f4e44657364745453542d346230653865": "1209004563918244f40000", "454c524f4e44657364744c5453542d346638343965": "1209000de0b6b3a763fc19", + "454c524f4e44657364745453542d393864633566": "1209004563918244f40000", + "454c524f4e44657364745453542d396230323030": "1209004563918244f40000", "454c524f4e44657364745453542d386564363538": "1209004563918244f40000", - "454c524f4e44657364745453542d343562383235": "12020064", - "454c524f4e446e6f6e636550544d2d353336666162": "01", + "454c524f4e44657364745453542d643862306438": "12020064", "454c524f4e44657364745453542d363835303064": "1209004563918244f40000", - "454c524f4e44657364745453542d336339363762": "12020064", - "454c524f4e446573647455544b2d313464353764": "120b0001e6ce88d5ebbfd00000", - "454c524f4e44657364745453542d363434633935": "12020064", - "454c524f4e44657364745453542d306632306637": "12020064", + "454c524f4e44657364745453542d323833633361": "12020064", "454c524f4e44657364745453542d333331386638": "1209004563918244f40000", - "454c524f4e44657364745453542d353538616434": "12020064", - "454c524f4e44657364745453542d363437383930": "1209004563918244f40000", - "454c524f4e44657364745453542d633933336139": "1209004563918244f40000", - "454c524f4e44657364745453542d393864633566": "1209004563918244f40000", "454c524f4e44657364745453542d303637373232": "1209004563918244f40000", - "454c524f4e44657364745453542d346634303238": "12020064", - "454c524f4e44657364745453542d643862306438": "12020064", - "454c524f4e44657364745453542d346230653865": "1209004563918244f40000", + "454c524f4e44657364745745474c442d613238633539": "120900389351ce08f09e12", "454c524f4e44657364745453542d343138613232": "1209004563918244f40000", - "454c524f4e44657364745453542d396230323030": "1209004563918244f40000", + "454c524f4e44657364745453542d656338383735": "12020064", + "454c524f4e44657364745453542d333639646531": "1209004563918244f40000", "454c524f4e44657364745453542d373639313337": "1209004563918244f40000", - "454c524f4e44657364745453542d303362373664": "12020064", + "454c524f4e44657364745453542d363434633935": "12020064", + "454c524f4e44657364745453542d623830663863": "1209004563918244f40000", + "454c524f4e4465736474475245454e2d306531363163": "120b00152d02c7e14af67fffdc", + "454c524f4e4465736474424358535542542d33393264366172": "080112020001", + "454c524f4e44657364745453542d343562383235": "12020064", "454c524f4e44657364745453542d613562663131": "12020064", - "454c524f4e44657364745453542d353966316165": "1209004563918244f40000", + "454c524f4e44657364745453542d623130616461": "1209004563918244f40000", + "454c524f4e44657364745453542d633933336139": "1209004563918244f40000", + "454c524f4e44657364744c5453542d376266336431": "1209000de0b6b3a763fc19", + "454c524f4e44657364745453542d336339363762": "12020064", "454c524f4e44657364745453542d623136363735": "1209004563918244f40000", - "454c524f4e44657364745453542d333639646531": "1209004563918244f40000", - "454c524f4e44657364745453542d623830663863": "1209004563918244f40000", - "454c524f4e44657364745453542d633565303835": "1209004563918244f40000" + "454c524f4e44657364745453542d303362373664": "12020064", + "454c524f4e44657364745453542d353538616434": "12020064", + "454c524f4e44657364745453542d353966316165": "1209004563918244f40000", + "454c524f4e44657364745453542d306632306637": "12020064", + "454c524f4e446573647455544b2d313464353764": "120b0001e6ce88d5ebbfd00000", + "454c524f4e44657364745453542d633636666535": "1209004563918244f40000", + "454c524f4e44657364745453542d346634303238": "12020064", + "454c524f4e44657364745453542d643964336136": "1209004563918244f40000", + "454c524f4e44657364745453542d343265356138": "1209004563918244f40000", + "454c524f4e44657364745453542d393836646663": "12020064" }, "code": "", "code_hash": "", @@ -58,19 +58,19 @@ "nonce": 1417, "balance": "1753855617144056", "keys": { + "454c524f4e4465736474424358535542542d3339326436616e": "080112020001", + "454c524f4e446573647442534b2d343736343730": "120b00021e19e0c9bab23fff7b", "454c524f4e446573647445564e544e4f544946592d393634383835": "120b00152d02c7e14af6800000", "454c524f4e4465736474494e5445524e532d63393332356601": "0801120b0013097d1fb962e12fff47", "454c524f4e44657364744e455453432d623635306261": "120b00d137965aa7a731800000", - "454c524f4e446e6f6e6365494e5445524e532d633933323566": "01", "454c524f4e44657364745745474c442d613238633539": "120800010593b233281b", + "454c524f4e446e6f6e6365494e5445524e532d633933323566": "01", "454c524f4e446e6f6e63654d4554414e46542d643062623339": "01", "454c524f4e44726f6c6565736474494e5445524e532d633933323566": "0a1145534454526f6c654e46544372656174650a1645534454526f6c654e46544164645175616e74697479", + "454c524f4e44657364744e4943552d393730323932": "120b00d3c21bcecceda1000000", "454c524f4e44726f6c65657364744d4554414e46542d643062623339": "0a1145534454526f6c654e4654437265617465", - "454c524f4e446573647442534b2d343736343730": "120b00021e19e0c9bab23fff7b", - "454c524f4e44657364744e45543253432d306438663962": "120f0004ee2d6d3f3d6bcc25c64dc00000", "454c524f4e4465736474424358535542542d3339326436616c": "080112020001", - "454c524f4e44657364744e4943552d393730323932": "120b00d3c21bcecceda1000000", - "454c524f4e4465736474424358535542542d3339326436616e": "080112020001" + "454c524f4e44657364744e45543253432d306438663962": "120f0004ee2d6d3f3d6bcc25c64dc00000" }, "code": "", "code_hash": "", diff --git a/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs b/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs index 6d217f66f3..b4e9747794 100644 --- a/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs +++ b/contracts/examples/adder/interactor/tests/basic_interactor_cs_test.rs @@ -1,7 +1,9 @@ use basic_interactor::{AdderInteract, Config}; use multiversx_sc_snippets::{imports::Bech32Address, sdk::gateway::SetStateAccount, test_wallets}; +use serial_test::serial; #[tokio::test] +#[serial] #[cfg_attr(not(feature = "chain-simulator-tests"), ignore)] async fn simulator_upgrade_test() { let mut basic_interact = AdderInteract::new(Config::chain_simulator_config()).await; @@ -36,6 +38,7 @@ async fn simulator_upgrade_test() { } #[tokio::test] +#[serial] #[cfg_attr(not(feature = "chain-simulator-tests"), ignore)] async fn set_state_cs_test() { let account_address = test_wallets::mike(); @@ -57,12 +60,17 @@ async fn set_state_cs_test() { let set_state_response = simulator_interact.interactor.set_state(vec_state).await; - let _ = simulator_interact.interactor.generate_blocks(2u64).await; + simulator_interact + .interactor + .generate_blocks(2u64) + .await + .unwrap(); assert!(set_state_response.is_ok()); } #[tokio::test] +#[serial] #[cfg_attr(not(feature = "chain-simulator-tests"), ignore)] async fn set_state_from_file_cs_test() { let account_address = test_wallets::mike(); From 2fac9aa2a4e0f216959582222c04f28f54f69900 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Thu, 28 Nov 2024 13:38:12 +0200 Subject: [PATCH 037/133] update mx-scenario-go v3.0.0 --- .github/workflows/actions-nightly.yml | 4 ++-- .github/workflows/actions.yml | 2 +- .github/workflows/template-test-current.yml | 2 +- .github/workflows/template-test-released.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/actions-nightly.yml b/.github/workflows/actions-nightly.yml index 2539363ff9..06be701e53 100644 --- a/.github/workflows/actions-nightly.yml +++ b/.github/workflows/actions-nightly.yml @@ -19,7 +19,7 @@ jobs: rust-toolchain: nightly-2024-05-22 path-to-sc-meta: framework/meta enable-contracts-size-report: false - mx-scenario-go-version: v2.1.0-alpha + mx-scenario-go-version: v3.0.0 coverage-args: --ignore-filename-regex='meta/src' --ignore-filename-regex='wasm-adapter' --ignore-filename-regex='benchmarks/' --ignore-filename-regex='tests/' --output ./coverage.md secrets: - token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 58ea9e80c6..d7bab07611 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -18,7 +18,7 @@ jobs: with: rust-toolchain: stable path-to-sc-meta: framework/meta - mx-scenario-go-version: v2.1.0-alpha + mx-scenario-go-version: v3.0.0 coverage-args: --ignore-filename-regex='meta/src' --ignore-filename-regex='wasm-adapter' --ignore-filename-regex='benchmarks/' --ignore-filename-regex='tests/' --output ./coverage.md secrets: token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/template-test-current.yml b/.github/workflows/template-test-current.yml index 56382850fe..9e52703919 100644 --- a/.github/workflows/template-test-current.yml +++ b/.github/workflows/template-test-current.yml @@ -29,7 +29,7 @@ jobs: run: | cargo install wasm-opt cargo install --path framework/meta - sc-meta install mx-scenario-go --tag v2.0.0 + sc-meta install mx-scenario-go --tag v3.0.0 which wasm-opt which mx-scenario-go diff --git a/.github/workflows/template-test-released.yml b/.github/workflows/template-test-released.yml index e6227765db..2e4e8f3ec5 100644 --- a/.github/workflows/template-test-released.yml +++ b/.github/workflows/template-test-released.yml @@ -29,7 +29,7 @@ jobs: run: | cargo install wasm-opt cargo install --path framework/meta - sc-meta install mx-scenario-go --tag v2.0.0 + sc-meta install mx-scenario-go --tag v3.0.0 which wasm-opt which mx-scenario-go From 4b320bedb5550325ce1608b2c1cf4aed4d85d126 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 28 Nov 2024 17:55:40 +0200 Subject: [PATCH 038/133] ManagedVecRefMut rename --- framework/base/src/types/{io/mod.rs => io.rs} | 0 .../base/src/types/{managed/mod.rs => managed.rs} | 0 .../src/types/managed/{wrapped/mod.rs => wrapped.rs} | 4 ++-- .../base/src/types/managed/wrapped/managed_vec.rs | 8 ++++---- .../{managed_vec_ref.rs => managed_vec_ref_mut.rs} | 10 +++++----- .../types/{static_buffer/mod.rs => static_buffer.rs} | 0 6 files changed, 11 insertions(+), 11 deletions(-) rename framework/base/src/types/{io/mod.rs => io.rs} (100%) rename framework/base/src/types/{managed/mod.rs => managed.rs} (100%) rename framework/base/src/types/managed/{wrapped/mod.rs => wrapped.rs} (96%) rename framework/base/src/types/managed/wrapped/{managed_vec_ref.rs => managed_vec_ref_mut.rs} (88%) rename framework/base/src/types/{static_buffer/mod.rs => static_buffer.rs} (100%) diff --git a/framework/base/src/types/io/mod.rs b/framework/base/src/types/io.rs similarity index 100% rename from framework/base/src/types/io/mod.rs rename to framework/base/src/types/io.rs diff --git a/framework/base/src/types/managed/mod.rs b/framework/base/src/types/managed.rs similarity index 100% rename from framework/base/src/types/managed/mod.rs rename to framework/base/src/types/managed.rs diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped.rs similarity index 96% rename from framework/base/src/types/managed/wrapped/mod.rs rename to framework/base/src/types/managed/wrapped.rs index 5086c3bc26..8e3efa278f 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped.rs @@ -20,8 +20,8 @@ mod managed_vec_item; mod managed_vec_item_nested_tuple; mod managed_vec_item_payload; mod managed_vec_owned_iter; -mod managed_vec_ref; mod managed_vec_ref_iter; +mod managed_vec_ref_mut; pub(crate) mod preloaded_managed_buffer; mod randomness_source; mod token_identifier; @@ -53,8 +53,8 @@ pub use managed_vec_item::{ pub use managed_vec_item_nested_tuple::ManagedVecItemNestedTuple; pub use managed_vec_item_payload::*; pub use managed_vec_owned_iter::ManagedVecOwnedIterator; -pub use managed_vec_ref::ManagedVecRef; pub use managed_vec_ref_iter::ManagedVecRefIterator; +pub use managed_vec_ref_mut::ManagedVecRefMut; pub use randomness_source::RandomnessSource; pub use token_identifier::TokenIdentifier; diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 2fd2d5fa3a..ab93734a06 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -8,8 +8,8 @@ use crate::{ TopEncodeMultiOutput, TopEncodeOutput, }, types::{ - ManagedBuffer, ManagedBufferNestedDecodeInput, ManagedType, ManagedVecItem, ManagedVecRef, - ManagedVecRefIterator, MultiValueEncoded, MultiValueManagedVec, + ManagedBuffer, ManagedBufferNestedDecodeInput, ManagedType, ManagedVecItem, + ManagedVecRefIterator, ManagedVecRefMut, MultiValueEncoded, MultiValueManagedVec, }, }; use alloc::{format, vec::Vec}; @@ -182,8 +182,8 @@ where } } - pub fn get_mut(&mut self, index: usize) -> ManagedVecRef { - ManagedVecRef::new(self.get_handle(), index) + pub fn get_mut(&mut self, index: usize) -> ManagedVecRefMut { + ManagedVecRefMut::new(self.get_handle(), index) } pub(super) unsafe fn get_unsafe(&self, index: usize) -> T { diff --git a/framework/base/src/types/managed/wrapped/managed_vec_ref.rs b/framework/base/src/types/managed/wrapped/managed_vec_ref_mut.rs similarity index 88% rename from framework/base/src/types/managed/wrapped/managed_vec_ref.rs rename to framework/base/src/types/managed/wrapped/managed_vec_ref_mut.rs index b339d1cdaf..b3ab840fd1 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref_mut.rs @@ -10,7 +10,7 @@ use core::{ use super::{ManagedRef, ManagedRefMut}; -pub struct ManagedVecRef<'a, M, T> +pub struct ManagedVecRefMut<'a, M, T> where M: ManagedTypeApi, T: ManagedVecItem, @@ -22,7 +22,7 @@ where item: ManuallyDrop, } -impl<'a, M, T> ManagedVecRef<'a, M, T> +impl<'a, M, T> ManagedVecRefMut<'a, M, T> where M: ManagedTypeApi, T: ManagedVecItem, @@ -47,7 +47,7 @@ where } } -impl<'a, M, T> Drop for ManagedVecRef<'a, M, T> +impl<'a, M, T> Drop for ManagedVecRefMut<'a, M, T> where M: ManagedTypeApi, T: ManagedVecItem, @@ -63,7 +63,7 @@ where } } -impl<'a, M, T> Deref for ManagedVecRef<'a, M, T> +impl<'a, M, T> Deref for ManagedVecRefMut<'a, M, T> where M: ManagedTypeApi, T: ManagedVecItem, @@ -75,7 +75,7 @@ where } } -impl<'a, M, T> DerefMut for ManagedVecRef<'a, M, T> +impl<'a, M, T> DerefMut for ManagedVecRefMut<'a, M, T> where M: ManagedTypeApi, T: ManagedVecItem, diff --git a/framework/base/src/types/static_buffer/mod.rs b/framework/base/src/types/static_buffer.rs similarity index 100% rename from framework/base/src/types/static_buffer/mod.rs rename to framework/base/src/types/static_buffer.rs From 69c69746c8e310b9c8c382ee06788f7037caef5c Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 28 Nov 2024 18:37:23 +0200 Subject: [PATCH 039/133] clippy fix (rustc 1.83.0) --- .../system_sc/system_sc_unimplemented.rs | 2 +- .../crypto-kitties/common/random/src/lib.rs | 1 + data/codec/src/impl_for_types/impl_phantom.rs | 1 - data/codec/src/single/nested_de_input_slice.rs | 2 +- data/codec/src/single/top_en_output.rs | 1 - framework/base/src/lib.rs | 1 + framework/base/src/storage/mappers/map_mapper.rs | 2 +- .../base/src/types/managed/basic/managed_buffer.rs | 1 - .../base/src/types/managed/wrapped/managed_ref.rs | 4 ++-- .../src/types/managed/wrapped/managed_ref_mut.rs | 14 +++++++------- .../meta/src/cmd/code_report/render_code_report.rs | 10 +++++----- framework/meta/src/cmd/template/template_source.rs | 2 +- framework/scenario/src/facade/expr/file_path.rs | 6 +++--- framework/scenario/src/lib.rs | 1 + .../interactor_tx/interactor_exec_env.rs | 6 +++--- .../interactor_tx/interactor_exec_transf.rs | 2 +- .../interactor_tx/interactor_query_env.rs | 4 ++-- framework/snippets/src/multi/interactor_step.rs | 2 +- framework/wasm-adapter/src/api/unsafe_buffer.rs | 2 ++ .../src/wasm_alloc/leaking_allocator.rs | 2 +- sdk/core/src/crypto/public_key.rs | 2 +- sdk/core/src/gateway/gateway_account.rs | 2 +- sdk/core/src/gateway/gateway_account_esdt_roles.rs | 2 +- .../src/gateway/gateway_account_esdt_tokens.rs | 2 +- sdk/core/src/gateway/gateway_account_storage.rs | 2 +- sdk/core/src/gateway/gateway_tx_cost.rs | 2 +- sdk/core/src/gateway/gateway_tx_info.rs | 2 +- sdk/core/src/gateway/gateway_tx_process_status.rs | 2 +- sdk/core/src/gateway/gateway_tx_send.rs | 2 +- sdk/core/src/gateway/gateway_tx_send_multi.rs | 2 +- sdk/core/src/gateway/gateway_tx_status.rs | 2 +- sdk/core/src/gateway/gateway_tx_vmquery.rs | 2 +- sdk/core/src/retrieve_tx_on_network.rs | 2 +- .../src/value_interpreter/reconstructor.rs | 2 +- 34 files changed, 48 insertions(+), 46 deletions(-) diff --git a/chain/vm/src/tx_execution/system_sc/system_sc_unimplemented.rs b/chain/vm/src/tx_execution/system_sc/system_sc_unimplemented.rs index cf93be7727..a324f34900 100644 --- a/chain/vm/src/tx_execution/system_sc/system_sc_unimplemented.rs +++ b/chain/vm/src/tx_execution/system_sc/system_sc_unimplemented.rs @@ -3,8 +3,8 @@ use crate::tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}; /// Every unimplemented fn will be implemented and moved to its corresponding file. +/// /// This file will be deleted. - pub fn register_meta_esdt(tx_input: TxInput, tx_cache: TxCache) -> (TxResult, BlockchainUpdate) { unimplemented!() } diff --git a/contracts/examples/crypto-kitties/common/random/src/lib.rs b/contracts/examples/crypto-kitties/common/random/src/lib.rs index 46ddd076d6..1cfb5e3fa2 100644 --- a/contracts/examples/crypto-kitties/common/random/src/lib.rs +++ b/contracts/examples/crypto-kitties/common/random/src/lib.rs @@ -24,6 +24,7 @@ pub trait Randomizeable { impl Random { /// block random seed + salt creates a stronger randomness source + #[allow(static_mut_refs)] pub fn new( seed: ManagedByteArray, salt: ManagedByteArray, diff --git a/data/codec/src/impl_for_types/impl_phantom.rs b/data/codec/src/impl_for_types/impl_phantom.rs index 6036152f02..60087753b6 100644 --- a/data/codec/src/impl_for_types/impl_phantom.rs +++ b/data/codec/src/impl_for_types/impl_phantom.rs @@ -8,7 +8,6 @@ use crate::{ /// Empty structure with an empty bytes representation. Equivalent to `false`, `0` or `[u8; 0]`, but more explicit. /// /// Note: the unit type `()` would have naturally fit this role, but we decided to make the unit type multi-value only. - impl TopEncode for PhantomData { #[inline] fn top_encode_or_handle_err(&self, output: O, _h: H) -> Result<(), H::HandledErr> diff --git a/data/codec/src/single/nested_de_input_slice.rs b/data/codec/src/single/nested_de_input_slice.rs index ce399a8de9..b0dd0eed51 100644 --- a/data/codec/src/single/nested_de_input_slice.rs +++ b/data/codec/src/single/nested_de_input_slice.rs @@ -1,7 +1,7 @@ use crate::{DecodeError, DecodeErrorHandler, NestedDecode, NestedDecodeInput}; /// A nested decode buffer implementation on referenced data. -impl<'a> NestedDecodeInput for &'a [u8] { +impl NestedDecodeInput for &[u8] { fn remaining_len(&self) -> usize { self.len() } diff --git a/data/codec/src/single/top_en_output.rs b/data/codec/src/single/top_en_output.rs index 4f955ca2f2..b2d2618d39 100644 --- a/data/codec/src/single/top_en_output.rs +++ b/data/codec/src/single/top_en_output.rs @@ -5,7 +5,6 @@ use crate::{ use alloc::vec::Vec; /// Specifies objects that can receive the result of a TopEncode computation. - /// in principle from NestedEncode performed on nested items. /// /// All methods consume the object, so they can only be called once. diff --git a/framework/base/src/lib.rs b/framework/base/src/lib.rs index 9f6680af7c..f6c765e67b 100644 --- a/framework/base/src/lib.rs +++ b/framework/base/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] #![allow(deprecated)] +#![allow(clippy::needless_lifetimes)] // TODO: fix them all! pub use multiversx_sc_derive::{self as derive, contract, module, proxy}; diff --git a/framework/base/src/storage/mappers/map_mapper.rs b/framework/base/src/storage/mappers/map_mapper.rs index 0da042334a..9e90917985 100644 --- a/framework/base/src/storage/mappers/map_mapper.rs +++ b/framework/base/src/storage/mappers/map_mapper.rs @@ -438,7 +438,7 @@ where } } -impl<'a, SA, A, K, V> VacantEntry<'a, SA, A, K, V> +impl VacantEntry<'_, SA, A, K, V> where SA: StorageMapperApi, A: StorageAddress, diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index cafa32a4d2..d3c0c28e38 100644 --- a/framework/base/src/types/managed/basic/managed_buffer.rs +++ b/framework/base/src/types/managed/basic/managed_buffer.rs @@ -94,7 +94,6 @@ impl ManagedBuffer { /// ## Safety /// /// The reference points to a shared value. Make sure the handle is not leaked. - pub unsafe fn temp_const_ref( raw_handle: RawHandle, ) -> ManagedRef<'static, M, ManagedBuffer> { diff --git a/framework/base/src/types/managed/wrapped/managed_ref.rs b/framework/base/src/types/managed/wrapped/managed_ref.rs index ef0e20fb9f..f618063b3c 100644 --- a/framework/base/src/types/managed/wrapped/managed_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_ref.rs @@ -143,7 +143,7 @@ where } } -impl<'a, M, T> NestedEncode for ManagedRef<'a, M, T> +impl NestedEncode for ManagedRef<'_, M, T> where M: ManagedTypeApi, T: ManagedType + NestedEncode, @@ -158,7 +158,7 @@ where } } -impl<'a, M, T> core::fmt::Debug for ManagedRef<'a, M, T> +impl core::fmt::Debug for ManagedRef<'_, M, T> where M: ManagedTypeApi, T: ManagedType + core::fmt::Debug, diff --git a/framework/base/src/types/managed/wrapped/managed_ref_mut.rs b/framework/base/src/types/managed/wrapped/managed_ref_mut.rs index 81315b89b2..868ef89e78 100644 --- a/framework/base/src/types/managed/wrapped/managed_ref_mut.rs +++ b/framework/base/src/types/managed/wrapped/managed_ref_mut.rs @@ -20,12 +20,12 @@ where pub(super) handle: T::OwnHandle, } -impl<'a, M, T> ManagedRefMut<'a, M, T> +impl ManagedRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedType, { - pub fn new(value: &'a mut T) -> Self { + pub fn new(value: &mut T) -> Self { Self { _phantom_m: PhantomData, _phantom_t: PhantomData, @@ -44,7 +44,7 @@ where } } -impl<'a, M, T> ManagedRefMut<'a, M, T> +impl ManagedRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedType + Clone, @@ -55,7 +55,7 @@ where } } -impl<'a, M, T> Clone for ManagedRefMut<'a, M, T> +impl Clone for ManagedRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedType, @@ -70,7 +70,7 @@ where } } -impl<'a, M, T> Deref for ManagedRefMut<'a, M, T> +impl Deref for ManagedRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedType, @@ -83,7 +83,7 @@ where } } -impl<'a, M, T> DerefMut for ManagedRefMut<'a, M, T> +impl DerefMut for ManagedRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedType, @@ -93,7 +93,7 @@ where } } -impl<'a, M, T> Borrow for ManagedRefMut<'a, M, T> +impl Borrow for ManagedRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedType, diff --git a/framework/meta/src/cmd/code_report/render_code_report.rs b/framework/meta/src/cmd/code_report/render_code_report.rs index e6edcfae8e..f72a05abdf 100644 --- a/framework/meta/src/cmd/code_report/render_code_report.rs +++ b/framework/meta/src/cmd/code_report/render_code_report.rs @@ -61,14 +61,14 @@ impl<'a> CodeReportRender<'a> { fn write_report_for_contract( &mut self, - path: &String, - size: &String, - has_allocator: &String, - has_panic: &String, + path: &str, + size: &str, + has_allocator: &str, + has_panic: &str, ) { self.writeln(format!( "| {} | {} | {} | {} |", - path.split('/').last().unwrap_or_else(|| path), + path.split('/').last().unwrap_or(path), size, has_allocator, has_panic diff --git a/framework/meta/src/cmd/template/template_source.rs b/framework/meta/src/cmd/template/template_source.rs index ea4140cd31..c8f83ac87e 100644 --- a/framework/meta/src/cmd/template/template_source.rs +++ b/framework/meta/src/cmd/template/template_source.rs @@ -16,7 +16,7 @@ pub struct TemplateSource<'a> { pub metadata: TemplateMetadata, } -impl<'a> TemplateSource<'a> { +impl TemplateSource<'_> { pub fn copy_template(&self, target_path: impl AsRef, args_tag: FrameworkVersion) { whitelisted_deep_copy( &self.source_path, diff --git a/framework/scenario/src/facade/expr/file_path.rs b/framework/scenario/src/facade/expr/file_path.rs index 8d779a6fd1..0c05165fb2 100644 --- a/framework/scenario/src/facade/expr/file_path.rs +++ b/framework/scenario/src/facade/expr/file_path.rs @@ -12,7 +12,7 @@ const FILE_PREFIX: &str = "file:"; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct FilePath<'a>(pub &'a str); -impl<'a> FilePath<'a> { +impl FilePath<'_> { pub fn eval_to_expr(&self) -> String { format!("{FILE_PREFIX}{}", self.0) } @@ -36,9 +36,9 @@ where } } -impl<'a, Env> TxCodeValue for FilePath<'a> where Env: ScenarioTxEnv {} +impl TxCodeValue for FilePath<'_> where Env: ScenarioTxEnv {} -impl<'a> RegisterCodeSource for FilePath<'a> { +impl RegisterCodeSource for FilePath<'_> { fn into_code(self, env_data: ScenarioTxEnvData) -> Vec { self.resolve_contents(&env_data.interpreter_context()) } diff --git a/framework/scenario/src/lib.rs b/framework/scenario/src/lib.rs index cfac7eaa50..46238e2ab9 100644 --- a/framework/scenario/src/lib.rs +++ b/framework/scenario/src/lib.rs @@ -1,4 +1,5 @@ #![allow(clippy::type_complexity)] +#![allow(clippy::needless_lifetimes)] // TODO: fix them all! pub mod api; pub mod bech32; diff --git a/framework/snippets/src/interactor/interactor_tx/interactor_exec_env.rs b/framework/snippets/src/interactor/interactor_tx/interactor_exec_env.rs index c7987d28e6..ba01813f9c 100644 --- a/framework/snippets/src/interactor/interactor_tx/interactor_exec_env.rs +++ b/framework/snippets/src/interactor/interactor_tx/interactor_exec_env.rs @@ -30,7 +30,7 @@ where pub data: ScenarioTxEnvData, } -impl<'w, GatewayProxy> TxEnv for InteractorEnvExec<'w, GatewayProxy> +impl TxEnv for InteractorEnvExec<'_, GatewayProxy> where GatewayProxy: GatewayAsyncService, { @@ -51,7 +51,7 @@ where } } -impl<'w, GatewayProxy> ScenarioTxEnv for InteractorEnvExec<'w, GatewayProxy> +impl ScenarioTxEnv for InteractorEnvExec<'_, GatewayProxy> where GatewayProxy: GatewayAsyncService, { @@ -60,7 +60,7 @@ where } } -impl<'w, GatewayProxy> TxEnvWithTxHash for InteractorEnvExec<'w, GatewayProxy> +impl TxEnvWithTxHash for InteractorEnvExec<'_, GatewayProxy> where GatewayProxy: GatewayAsyncService, { diff --git a/framework/snippets/src/interactor/interactor_tx/interactor_exec_transf.rs b/framework/snippets/src/interactor/interactor_tx/interactor_exec_transf.rs index bb7559ba93..1dade9dc6b 100644 --- a/framework/snippets/src/interactor/interactor_tx/interactor_exec_transf.rs +++ b/framework/snippets/src/interactor/interactor_tx/interactor_exec_transf.rs @@ -54,7 +54,7 @@ where } } -impl<'w, GatewayProxy> InteractorExecStep<'w, GatewayProxy, TransferStep, ()> +impl InteractorExecStep<'_, GatewayProxy, TransferStep, ()> where GatewayProxy: GatewayAsyncService, { diff --git a/framework/snippets/src/interactor/interactor_tx/interactor_query_env.rs b/framework/snippets/src/interactor/interactor_tx/interactor_query_env.rs index 25d0b5e822..dbd2066a66 100644 --- a/framework/snippets/src/interactor/interactor_tx/interactor_query_env.rs +++ b/framework/snippets/src/interactor/interactor_tx/interactor_query_env.rs @@ -27,7 +27,7 @@ where pub data: ScenarioTxEnvData, } -impl<'w, GatewayProxy> TxEnv for InteractorEnvQuery<'w, GatewayProxy> +impl TxEnv for InteractorEnvQuery<'_, GatewayProxy> where GatewayProxy: GatewayAsyncService, { @@ -48,7 +48,7 @@ where } } -impl<'w, GatewayProxy> ScenarioTxEnv for InteractorEnvQuery<'w, GatewayProxy> +impl ScenarioTxEnv for InteractorEnvQuery<'_, GatewayProxy> where GatewayProxy: GatewayAsyncService, { diff --git a/framework/snippets/src/multi/interactor_step.rs b/framework/snippets/src/multi/interactor_step.rs index 93a93d6a9e..b8df05a9a5 100644 --- a/framework/snippets/src/multi/interactor_step.rs +++ b/framework/snippets/src/multi/interactor_step.rs @@ -13,7 +13,7 @@ pub enum InteractorStepRef<'a> { ScDeploy(&'a mut ScDeployStep), } -impl<'a> InteractorStepRef<'a> { +impl InteractorStepRef<'_> { pub fn to_transaction( &self, interactor: &InteractorBase, diff --git a/framework/wasm-adapter/src/api/unsafe_buffer.rs b/framework/wasm-adapter/src/api/unsafe_buffer.rs index c18034de6b..8794203daa 100644 --- a/framework/wasm-adapter/src/api/unsafe_buffer.rs +++ b/framework/wasm-adapter/src/api/unsafe_buffer.rs @@ -11,10 +11,12 @@ static mut BUFFER_1: [u8; BUFFER_1_SIZE] = [0u8; BUFFER_1_SIZE]; /// The second buffer is for when the first one is busy with something else. static mut BUFFER_2: [u8; BUFFER_2_SIZE] = [0u8; BUFFER_2_SIZE]; +#[allow(static_mut_refs)] pub(crate) unsafe fn buffer_1_ptr() -> *mut u8 { BUFFER_1.as_mut_ptr() } +#[allow(static_mut_refs)] pub(crate) unsafe fn buffer_2_ptr() -> *mut u8 { BUFFER_2.as_mut_ptr() } diff --git a/framework/wasm-adapter/src/wasm_alloc/leaking_allocator.rs b/framework/wasm-adapter/src/wasm_alloc/leaking_allocator.rs index 8a40b0ac68..06e246f0e4 100644 --- a/framework/wasm-adapter/src/wasm_alloc/leaking_allocator.rs +++ b/framework/wasm-adapter/src/wasm_alloc/leaking_allocator.rs @@ -45,7 +45,7 @@ unsafe impl GlobalAlloc for LeakingAllocator { if new_total > *size { // Request enough new space for this allocation, even if we have some space left over from the last one incase they end up non-contiguous. // Round up to a number of pages - let requested_pages = (requested_size + PAGE_SIZE - 1) / PAGE_SIZE; + let requested_pages = requested_size.div_ceil(PAGE_SIZE); let previous_page_count = memory_grow(PageCount(requested_pages)); let previous_size = previous_page_count.size_in_bytes(); diff --git a/sdk/core/src/crypto/public_key.rs b/sdk/core/src/crypto/public_key.rs index 448bf57e9d..6ad8604ecb 100644 --- a/sdk/core/src/crypto/public_key.rs +++ b/sdk/core/src/crypto/public_key.rs @@ -34,7 +34,7 @@ impl PublicKey { } } -impl<'a> From<&'a PrivateKey> for PublicKey { +impl From<&PrivateKey> for PublicKey { fn from(private_key: &PrivateKey) -> PublicKey { let bytes = private_key.to_bytes(); diff --git a/sdk/core/src/gateway/gateway_account.rs b/sdk/core/src/gateway/gateway_account.rs index 76eee4c736..913c55d0eb 100644 --- a/sdk/core/src/gateway/gateway_account.rs +++ b/sdk/core/src/gateway/gateway_account.rs @@ -16,7 +16,7 @@ impl<'a> GetAccountRequest<'a> { } } -impl<'a> GatewayRequest for GetAccountRequest<'a> { +impl GatewayRequest for GetAccountRequest<'_> { type Payload = (); type DecodedJson = AccountResponse; type Result = Account; diff --git a/sdk/core/src/gateway/gateway_account_esdt_roles.rs b/sdk/core/src/gateway/gateway_account_esdt_roles.rs index 421edd81b2..d7b19e8e41 100644 --- a/sdk/core/src/gateway/gateway_account_esdt_roles.rs +++ b/sdk/core/src/gateway/gateway_account_esdt_roles.rs @@ -16,7 +16,7 @@ impl<'a> GetAccountEsdtRolesRequest<'a> { } } -impl<'a> GatewayRequest for GetAccountEsdtRolesRequest<'a> { +impl GatewayRequest for GetAccountEsdtRolesRequest<'_> { type Payload = (); type DecodedJson = EsdtRolesResponse; type Result = HashMap>; diff --git a/sdk/core/src/gateway/gateway_account_esdt_tokens.rs b/sdk/core/src/gateway/gateway_account_esdt_tokens.rs index 72e27e54a9..e2916fe840 100644 --- a/sdk/core/src/gateway/gateway_account_esdt_tokens.rs +++ b/sdk/core/src/gateway/gateway_account_esdt_tokens.rs @@ -16,7 +16,7 @@ impl<'a> GetAccountEsdtTokensRequest<'a> { } } -impl<'a> GatewayRequest for GetAccountEsdtTokensRequest<'a> { +impl GatewayRequest for GetAccountEsdtTokensRequest<'_> { type Payload = (); type DecodedJson = EsdtBalanceResponse; type Result = HashMap; diff --git a/sdk/core/src/gateway/gateway_account_storage.rs b/sdk/core/src/gateway/gateway_account_storage.rs index 6c1bffe55f..011d29d460 100644 --- a/sdk/core/src/gateway/gateway_account_storage.rs +++ b/sdk/core/src/gateway/gateway_account_storage.rs @@ -16,7 +16,7 @@ impl<'a> GetAccountStorageRequest<'a> { } } -impl<'a> GatewayRequest for GetAccountStorageRequest<'a> { +impl GatewayRequest for GetAccountStorageRequest<'_> { type Payload = (); type DecodedJson = AccountStorageResponse; type Result = HashMap; diff --git a/sdk/core/src/gateway/gateway_tx_cost.rs b/sdk/core/src/gateway/gateway_tx_cost.rs index 333b0324c5..3ca8eff823 100644 --- a/sdk/core/src/gateway/gateway_tx_cost.rs +++ b/sdk/core/src/gateway/gateway_tx_cost.rs @@ -8,7 +8,7 @@ use super::{GatewayRequest, GatewayRequestType, COST_TRANSACTION_ENDPOINT}; /// Note: it is a POST request. pub struct GetTxCost<'a>(pub &'a Transaction); -impl<'a> GatewayRequest for GetTxCost<'a> { +impl GatewayRequest for GetTxCost<'_> { type Payload = Transaction; type DecodedJson = ResponseTxCost; type Result = TxCostResponseData; diff --git a/sdk/core/src/gateway/gateway_tx_info.rs b/sdk/core/src/gateway/gateway_tx_info.rs index f4d26e9d44..d9cc12d02b 100644 --- a/sdk/core/src/gateway/gateway_tx_info.rs +++ b/sdk/core/src/gateway/gateway_tx_info.rs @@ -27,7 +27,7 @@ impl<'a> GetTxInfo<'a> { } } -impl<'a> GatewayRequest for GetTxInfo<'a> { +impl GatewayRequest for GetTxInfo<'_> { type Payload = (); type DecodedJson = TransactionInfo; type Result = TransactionOnNetwork; diff --git a/sdk/core/src/gateway/gateway_tx_process_status.rs b/sdk/core/src/gateway/gateway_tx_process_status.rs index d829cb60fe..103bb4e4a6 100644 --- a/sdk/core/src/gateway/gateway_tx_process_status.rs +++ b/sdk/core/src/gateway/gateway_tx_process_status.rs @@ -14,7 +14,7 @@ impl<'a> GetTxProcessStatus<'a> { } } -impl<'a> GatewayRequest for GetTxProcessStatus<'a> { +impl GatewayRequest for GetTxProcessStatus<'_> { type Payload = (); type DecodedJson = TransactionProcessStatus; type Result = (String, String); diff --git a/sdk/core/src/gateway/gateway_tx_send.rs b/sdk/core/src/gateway/gateway_tx_send.rs index a76354df8e..4c3b9d584a 100644 --- a/sdk/core/src/gateway/gateway_tx_send.rs +++ b/sdk/core/src/gateway/gateway_tx_send.rs @@ -6,7 +6,7 @@ use super::{GatewayRequest, GatewayRequestType, SEND_TRANSACTION_ENDPOINT}; /// Sends a single transaction. pub struct SendTxRequest<'a>(pub &'a Transaction); -impl<'a> GatewayRequest for SendTxRequest<'a> { +impl GatewayRequest for SendTxRequest<'_> { type Payload = Transaction; type DecodedJson = SendTransactionResponse; type Result = String; diff --git a/sdk/core/src/gateway/gateway_tx_send_multi.rs b/sdk/core/src/gateway/gateway_tx_send_multi.rs index 472beaf5ba..8be1d1d4c0 100644 --- a/sdk/core/src/gateway/gateway_tx_send_multi.rs +++ b/sdk/core/src/gateway/gateway_tx_send_multi.rs @@ -7,7 +7,7 @@ use super::{GatewayRequest, GatewayRequestType, SEND_MULTIPLE_TRANSACTIONS_ENDPO /// Sends multiple transactions at once. pub struct SendMultiTxRequest<'a>(pub &'a [Transaction]); -impl<'a> GatewayRequest for SendMultiTxRequest<'a> { +impl GatewayRequest for SendMultiTxRequest<'_> { type Payload = [Transaction]; type DecodedJson = SendTransactionsResponse; type Result = Vec; diff --git a/sdk/core/src/gateway/gateway_tx_status.rs b/sdk/core/src/gateway/gateway_tx_status.rs index ac4e37e6b4..12660a2c57 100644 --- a/sdk/core/src/gateway/gateway_tx_status.rs +++ b/sdk/core/src/gateway/gateway_tx_status.rs @@ -14,7 +14,7 @@ impl<'a> GetTxStatus<'a> { } } -impl<'a> GatewayRequest for GetTxStatus<'a> { +impl GatewayRequest for GetTxStatus<'_> { type Payload = (); type DecodedJson = TransactionStatus; type Result = String; diff --git a/sdk/core/src/gateway/gateway_tx_vmquery.rs b/sdk/core/src/gateway/gateway_tx_vmquery.rs index e1523571da..9de88f6d2f 100644 --- a/sdk/core/src/gateway/gateway_tx_vmquery.rs +++ b/sdk/core/src/gateway/gateway_tx_vmquery.rs @@ -6,7 +6,7 @@ use super::{GatewayRequest, GatewayRequestType, VM_VALUES_ENDPOINT}; /// Executes a VM query. pub struct VMQueryRequest<'a>(pub &'a VMQueryInput); -impl<'a> GatewayRequest for VMQueryRequest<'a> { +impl GatewayRequest for VMQueryRequest<'_> { type Payload = VMQueryInput; type DecodedJson = ResponseVmValue; type Result = VmValuesResponseData; diff --git a/sdk/core/src/retrieve_tx_on_network.rs b/sdk/core/src/retrieve_tx_on_network.rs index 3cfcf9fc77..3c60a92fa2 100644 --- a/sdk/core/src/retrieve_tx_on_network.rs +++ b/sdk/core/src/retrieve_tx_on_network.rs @@ -138,7 +138,7 @@ pub fn extract_message_from_string_reason(reason: &str) -> String { return message[0].to_string(); } - return contract_error.last().unwrap_or(&"").split(']').collect(); + contract_error.last().unwrap_or(&"").split(']').collect() } fn create_tx_failed(error_message: &str) -> TransactionOnNetwork { diff --git a/sdk/scenario-format/src/value_interpreter/reconstructor.rs b/sdk/scenario-format/src/value_interpreter/reconstructor.rs index 6efacefba4..e21a298905 100644 --- a/sdk/scenario-format/src/value_interpreter/reconstructor.rs +++ b/sdk/scenario-format/src/value_interpreter/reconstructor.rs @@ -147,7 +147,7 @@ fn can_interpret_as_string(bytes: &[u8]) -> bool { if bytes.is_empty() { return false; } - return !bytes.iter().any(|&b| !(32..=126).contains(&b)); + !bytes.iter().any(|&b| !(32..=126).contains(&b)) } fn code_pretty(bytes: &[u8]) -> String { From d173698762be2e4d7be5ab1dd379c0915a8625ec Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 28 Nov 2024 18:44:43 +0200 Subject: [PATCH 040/133] clippy fix --- .../base/src/types/managed/wrapped/managed_vec_ref_mut.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_ref_mut.rs b/framework/base/src/types/managed/wrapped/managed_vec_ref_mut.rs index b3ab840fd1..37a642648f 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_ref_mut.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref_mut.rs @@ -22,7 +22,7 @@ where item: ManuallyDrop, } -impl<'a, M, T> ManagedVecRefMut<'a, M, T> +impl ManagedVecRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedVecItem, @@ -47,7 +47,7 @@ where } } -impl<'a, M, T> Drop for ManagedVecRefMut<'a, M, T> +impl Drop for ManagedVecRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedVecItem, @@ -63,7 +63,7 @@ where } } -impl<'a, M, T> Deref for ManagedVecRefMut<'a, M, T> +impl Deref for ManagedVecRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedVecItem, @@ -75,7 +75,7 @@ where } } -impl<'a, M, T> DerefMut for ManagedVecRefMut<'a, M, T> +impl DerefMut for ManagedVecRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedVecItem, From 31c3a9a3e2382352a66c3630331153e2300b1954 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 28 Nov 2024 19:13:37 +0200 Subject: [PATCH 041/133] ManagedVecItem - lo longer implemented for handles directly --- .../base/src/api/managed_types/handles.rs | 7 ++---- .../src/api/impl_vh/debug_handle_vh.rs | 23 +------------------ 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/framework/base/src/api/managed_types/handles.rs b/framework/base/src/api/managed_types/handles.rs index 5a8f17ba9d..4c4c89a719 100644 --- a/framework/base/src/api/managed_types/handles.rs +++ b/framework/base/src/api/managed_types/handles.rs @@ -10,15 +10,12 @@ pub trait HandleTypeInfo { use crate::codec::TryStaticCast; -use crate::{ - api::{ErrorApi, ErrorApiImpl}, - types::ManagedVecItem, -}; +use crate::api::{ErrorApi, ErrorApiImpl}; pub type RawHandle = i32; pub trait HandleConstraints: - ManagedVecItem + TryStaticCast + Debug + Clone + From + PartialEq + PartialEq + TryStaticCast + Debug + Clone + From + PartialEq + PartialEq { fn new(handle: RawHandle) -> Self; fn to_be_bytes(&self) -> [u8; 4]; diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 64fcd15fa9..5c2a60c022 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -1,8 +1,7 @@ use multiversx_chain_vm::tx_mock::{TxContext, TxContextStack}; use multiversx_sc::{ - api::{use_raw_handle, HandleConstraints, RawHandle}, + api::{HandleConstraints, RawHandle}, codec::TryStaticCast, - types::ManagedVecItem, }; use std::sync::Arc; @@ -76,24 +75,4 @@ impl From for DebugHandle { } } -impl ManagedVecItem for DebugHandle { - type PAYLOAD = ::PAYLOAD; - - const SKIPS_RESERIALIZATION: bool = ::SKIPS_RESERIALIZATION; - - type Ref<'a> = Self; - - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - use_raw_handle(RawHandle::read_from_payload(payload)) - } - - unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { - Self::read_from_payload(payload) - } - - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { - self.get_raw_handle().save_to_payload(payload); - } -} - impl TryStaticCast for DebugHandle {} From 16fac80f5e22e8d0c85cb1ca588edb5e1aa57f0c Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 29 Nov 2024 10:58:10 +0200 Subject: [PATCH 042/133] ManagedVecItem - struct derive yields ManagedVecRef --- .../examples/order-book/pair/src/common.rs | 2 +- .../examples/order-book/pair/src/events.rs | 8 +-- .../examples/order-book/pair/src/orders.rs | 2 +- .../src/rewards_distribution.rs | 6 +-- .../src/distribution_module.rs | 2 +- .../src/governance/governance_proposal.rs | 2 +- contracts/modules/src/governance/mod.rs | 4 +- .../esdt_token_payment_multi_value.rs | 7 ++- framework/base/src/types/managed/wrapped.rs | 2 + .../types/managed/wrapped/managed_vec_item.rs | 6 +-- .../types/managed/wrapped/managed_vec_ref.rs | 54 +++++++++++++++++++ .../derive/src/managed_vec_item_derive.rs | 5 +- 12 files changed, 77 insertions(+), 23 deletions(-) create mode 100644 framework/base/src/types/managed/wrapped/managed_vec_ref.rs diff --git a/contracts/examples/order-book/pair/src/common.rs b/contracts/examples/order-book/pair/src/common.rs index 7728e4c364..85b1c1bca8 100644 --- a/contracts/examples/order-book/pair/src/common.rs +++ b/contracts/examples/order-book/pair/src/common.rs @@ -8,7 +8,7 @@ pub const FREE_ORDER_FROM_STORAGE_MIN_PENALTIES: u64 = 6; #[type_abi] #[derive( - ManagedVecItem, TopEncode, TopDecode, NestedEncode, NestedDecode, PartialEq, Eq, Clone, + ManagedVecItem, TopEncode, TopDecode, NestedEncode, NestedDecode, PartialEq, Eq, Clone, Copy )] pub enum OrderType { Buy, diff --git a/contracts/examples/order-book/pair/src/events.rs b/contracts/examples/order-book/pair/src/events.rs index ddbd6a3496..f20331f44f 100644 --- a/contracts/examples/order-book/pair/src/events.rs +++ b/contracts/examples/order-book/pair/src/events.rs @@ -31,7 +31,7 @@ pub trait EventsModule { for order in orders.iter() { let order_type = order.order_type; let order_id = order.id; - let order_creator = order.creator; + let order_creator = &order.creator; self.match_order_event(&caller, epoch, order_type, order_id, order_creator); } @@ -44,7 +44,7 @@ pub trait EventsModule { for order in orders.iter() { let order_type = order.order_type; let order_id = order.id; - let order_creator = order.creator; + let order_creator = &order.creator; self.free_order_event(&caller, epoch, order_type, order_id, order_creator); } @@ -75,7 +75,7 @@ pub trait EventsModule { #[indexed] epoch: u64, #[indexed] order_type: OrderType, #[indexed] order_id: u64, - #[indexed] order_creator: ManagedAddress, + #[indexed] order_creator: &ManagedAddress, ); #[event("free_order")] @@ -85,6 +85,6 @@ pub trait EventsModule { #[indexed] epoch: u64, #[indexed] order_type: OrderType, #[indexed] order_id: u64, - #[indexed] order_creator: ManagedAddress, + #[indexed] order_creator: &ManagedAddress, ); } diff --git a/contracts/examples/order-book/pair/src/orders.rs b/contracts/examples/order-book/pair/src/orders.rs index 1ec11afee4..2452cb0b16 100644 --- a/contracts/examples/order-book/pair/src/orders.rs +++ b/contracts/examples/order-book/pair/src/orders.rs @@ -282,7 +282,7 @@ pub trait OrdersModule: let mut orders_vec = MultiValueManagedVec::new(); for order in orders.iter() { if order.order_type == order_type { - orders_vec.push(order); + orders_vec.push(order.clone()); } } diff --git a/contracts/examples/rewards-distribution/src/rewards_distribution.rs b/contracts/examples/rewards-distribution/src/rewards_distribution.rs index 7300fcaf88..ecbf2b7d7c 100644 --- a/contracts/examples/rewards-distribution/src/rewards_distribution.rs +++ b/contracts/examples/rewards-distribution/src/rewards_distribution.rs @@ -21,7 +21,7 @@ pub struct Bracket { } #[type_abi] -#[derive(ManagedVecItem, NestedEncode, NestedDecode)] +#[derive(ManagedVecItem, NestedEncode, NestedDecode, Clone)] pub struct ComputedBracket { pub end_index: u64, pub nft_reward_percent: BigUint, @@ -74,7 +74,7 @@ pub trait RewardsDistribution: .unwrap_or_else(|| self.new_raffle()); let mut rng = RandomnessSource::default(); - let mut bracket = raffle.computed_brackets.get(0); + let mut bracket = raffle.computed_brackets.get(0).clone(); let run_result = self.run_while_it_has_gas(DEFAULT_MIN_GAS_TO_SAVE_PROGRESS, || { let ticket = self.shuffle_and_pick_single_ticket( @@ -138,7 +138,7 @@ pub trait RewardsDistribution: ) { while ticket > bracket.end_index { computed_brackets.remove(0); - *bracket = computed_brackets.get(0); + *bracket = computed_brackets.get(0).clone(); } } diff --git a/contracts/examples/seed-nft-minter/src/distribution_module.rs b/contracts/examples/seed-nft-minter/src/distribution_module.rs index 54f8bf2586..cebd751806 100644 --- a/contracts/examples/seed-nft-minter/src/distribution_module.rs +++ b/contracts/examples/seed-nft-minter/src/distribution_module.rs @@ -35,7 +35,7 @@ pub trait DistributionModule { } self.tx() .to(&distribution.address) - .raw_call(distribution.endpoint) + .raw_call(distribution.endpoint.clone()) .egld_or_single_esdt(token_id, token_nonce, &payment_amount) .gas(distribution.gas_limit) .transfer_execute(); diff --git a/contracts/modules/src/governance/governance_proposal.rs b/contracts/modules/src/governance/governance_proposal.rs index 60d0fa27f0..db3f28038d 100644 --- a/contracts/modules/src/governance/governance_proposal.rs +++ b/contracts/modules/src/governance/governance_proposal.rs @@ -36,7 +36,7 @@ pub struct ProposalFees { } #[type_abi] -#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, ManagedVecItem)] +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, ManagedVecItem, Clone)] pub struct FeeEntry { pub depositor_addr: ManagedAddress, pub tokens: EsdtTokenPayment, diff --git a/contracts/modules/src/governance/mod.rs b/contracts/modules/src/governance/mod.rs index 92eeb038db..85dfa4e1b4 100644 --- a/contracts/modules/src/governance/mod.rs +++ b/contracts/modules/src/governance/mod.rs @@ -74,7 +74,7 @@ pub trait GovernanceModule: let mut i = 0; while i < proposal.fees.entries.len() { if proposal.fees.entries.get(i).depositor_addr == caller { - fees_to_send.push(proposal.fees.entries.get(i)); + fees_to_send.push(proposal.fees.entries.get(i).clone()); proposal.fees.entries.remove(i); } else { i += 1; @@ -417,7 +417,7 @@ pub trait GovernanceModule: let payments = self.proposals().get(proposal_id).fees; for fee_entry in payments.entries.iter() { - let payment = fee_entry.tokens; + let payment = &fee_entry.tokens; self.tx() .to(&fee_entry.depositor_addr) .single_esdt( diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index d881b6a995..1d87fb2274 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -3,7 +3,7 @@ use crate::{ codec::{ multi_types::MultiValue3, DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput, TopDecodeMultiLength, TopEncodeMulti, TopEncodeMultiOutput, - }, + }, types::ManagedVecRef, }; use crate::{ @@ -42,15 +42,14 @@ impl EsdtTokenPaymentMultiValue { impl ManagedVecItem for EsdtTokenPaymentMultiValue { type PAYLOAD = as ManagedVecItem>::PAYLOAD; const SKIPS_RESERIALIZATION: bool = EsdtTokenPayment::::SKIPS_RESERIALIZATION; - type Ref<'a> = Self; + type Ref<'a> = ManagedVecRef<'a, Self>; fn read_from_payload(payload: &Self::PAYLOAD) -> Self { EsdtTokenPayment::read_from_payload(payload).into() } unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { - // TODO: managed ref - Self::read_from_payload(payload) + ManagedVecRef::new(Self::read_from_payload(payload)) } fn save_to_payload(self, payload: &mut Self::PAYLOAD) { diff --git a/framework/base/src/types/managed/wrapped.rs b/framework/base/src/types/managed/wrapped.rs index 8e3efa278f..088a250d5d 100644 --- a/framework/base/src/types/managed/wrapped.rs +++ b/framework/base/src/types/managed/wrapped.rs @@ -20,6 +20,7 @@ mod managed_vec_item; mod managed_vec_item_nested_tuple; mod managed_vec_item_payload; mod managed_vec_owned_iter; +mod managed_vec_ref; mod managed_vec_ref_iter; mod managed_vec_ref_mut; pub(crate) mod preloaded_managed_buffer; @@ -53,6 +54,7 @@ pub use managed_vec_item::{ pub use managed_vec_item_nested_tuple::ManagedVecItemNestedTuple; pub use managed_vec_item_payload::*; pub use managed_vec_owned_iter::ManagedVecOwnedIterator; +pub use managed_vec_ref::ManagedVecRef; pub use managed_vec_ref_iter::ManagedVecRefIterator; pub use managed_vec_ref_mut::ManagedVecRefMut; pub use randomness_source::RandomnessSource; diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 65ed262a41..d14ae0067f 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -13,7 +13,7 @@ use crate::{ use super::{ ManagedVecItemNestedTuple, ManagedVecItemPayload, ManagedVecItemPayloadAdd, - ManagedVecItemPayloadBuffer, + ManagedVecItemPayloadBuffer, ManagedVecRef, }; /// Types that implement this trait can be items inside a `ManagedVec`. @@ -168,7 +168,7 @@ where { type PAYLOAD = as ManagedVecItemPayloadAdd>::Output; const SKIPS_RESERIALIZATION: bool = false; - type Ref<'a> = Self; + type Ref<'a> = ManagedVecRef<'a, Self>; fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let (p1, p2) = as ManagedVecItemPayloadAdd< @@ -184,7 +184,7 @@ where } unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { - Self::read_from_payload(payload) + ManagedVecRef::new(Self::read_from_payload(payload)) } fn save_to_payload(self, payload: &mut Self::PAYLOAD) { diff --git a/framework/base/src/types/managed/wrapped/managed_vec_ref.rs b/framework/base/src/types/managed/wrapped/managed_vec_ref.rs new file mode 100644 index 0000000000..987cb60614 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref.rs @@ -0,0 +1,54 @@ +use crate::types::ManagedVecItem; +use core::{borrow::Borrow, marker::PhantomData, mem::ManuallyDrop, ops::Deref}; + +pub struct ManagedVecRef<'a, T> +where + T: ManagedVecItem, +{ + _phantom: PhantomData<&'a T>, // needed for the lifetime, even though T is present + item: ManuallyDrop, +} + +impl ManagedVecRef<'_, T> +where + T: ManagedVecItem, +{ + pub unsafe fn new(item: T) -> Self { + ManagedVecRef { + _phantom: PhantomData, + item: ManuallyDrop::new(item), + } + } +} + +impl Drop for ManagedVecRef<'_, T> +where + T: ManagedVecItem, +{ + fn drop(&mut self) { + // TODO: improve + unsafe { + ManuallyDrop::drop(&mut self.item); + } + } +} + +impl Deref for ManagedVecRef<'_, T> +where + T: ManagedVecItem, +{ + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.item + } +} + +impl Borrow for ManagedVecRef<'_, T> +where + T: ManagedVecItem, +{ + fn borrow(&self) -> &T { + self.deref() + } +} diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index 1531b00610..f9d7d52671 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -143,7 +143,7 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token impl #impl_generics multiversx_sc::types::ManagedVecItem for #name #ty_generics #where_clause { type PAYLOAD = <#payload_nested_tuple as multiversx_sc::types::ManagedVecItemNestedTuple>::PAYLOAD; const SKIPS_RESERIALIZATION: bool = #(#skips_reserialization_snippets)&&*; - type Ref<'a> = Self; + type Ref<'a> = multiversx_sc::types::ManagedVecRef<'a, Self>; fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; @@ -156,8 +156,7 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token } unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { - // TODO: managed ref - Self::read_from_payload(payload) + multiversx_sc::types::ManagedVecRef::new(Self::read_from_payload(payload)) } fn save_to_payload(self, payload: &mut Self::PAYLOAD) { From baf458e027f0721d18f43dc512570602eb3f2850 Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Fri, 29 Nov 2024 13:24:58 +0200 Subject: [PATCH 043/133] remove #![allow(clippy::needless_lifetimes)] --- framework/base/src/lib.rs | 2 -- framework/scenario/src/lib.rs | 1 - 2 files changed, 3 deletions(-) diff --git a/framework/base/src/lib.rs b/framework/base/src/lib.rs index f6c765e67b..b063a8d94a 100644 --- a/framework/base/src/lib.rs +++ b/framework/base/src/lib.rs @@ -1,7 +1,5 @@ #![no_std] #![allow(deprecated)] -#![allow(clippy::needless_lifetimes)] // TODO: fix them all! - pub use multiversx_sc_derive::{self as derive, contract, module, proxy}; // re-export basic heap types diff --git a/framework/scenario/src/lib.rs b/framework/scenario/src/lib.rs index 46238e2ab9..cfac7eaa50 100644 --- a/framework/scenario/src/lib.rs +++ b/framework/scenario/src/lib.rs @@ -1,5 +1,4 @@ #![allow(clippy::type_complexity)] -#![allow(clippy::needless_lifetimes)] // TODO: fix them all! pub mod api; pub mod bech32; From b60559726fe853f47bf2ce1dc52e3637c90bb57c Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Fri, 29 Nov 2024 13:28:59 +0200 Subject: [PATCH 044/133] easy `cargo clippy --tests --fix` --- framework/base/src/hex_call_data/cd_de.rs | 2 +- .../base/src/storage/mappers/bi_di_mapper.rs | 2 +- .../src/storage/mappers/linked_list_mapper.rs | 2 +- .../base/src/storage/mappers/map_mapper.rs | 10 ++++---- .../src/storage/mappers/map_storage_mapper.rs | 10 ++++---- .../base/src/storage/mappers/queue_mapper.rs | 2 +- .../src/storage/mappers/unique_id_mapper.rs | 2 +- .../base/src/storage/mappers/vec_mapper.rs | 2 +- framework/base/src/storage/storage_get.rs | 2 +- .../src/storage/storage_get_from_address.rs | 2 +- framework/base/src/storage/storage_set.rs | 2 +- .../annotated/annotated_impl_big_uint.rs | 2 +- .../types/interaction/expr/test_address.rs | 20 ++++++++-------- .../types/interaction/expr/test_sc_address.rs | 24 +++++++++---------- .../interaction/expr/test_token_identifier.rs | 6 ++--- .../tx_payment/test_esdt_transfer.rs | 2 +- .../tx_payment_egld_or_esdt_refs.rs | 2 +- .../tx_payment_egld_or_multi_esdt_ref.rs | 2 +- .../tx_payment/tx_payment_egld_value.rs | 2 +- .../tx_payment/tx_payment_multi_esdt.rs | 4 ++-- .../tx_payment/tx_payment_single_esdt_ref.rs | 2 +- .../wrapped/egld_or_esdt_token_identifier.rs | 4 ++-- .../wrapped/egld_or_multi_esdt_payment.rs | 2 +- .../src/types/managed/wrapped/managed_ref.rs | 14 +++++------ .../types/managed/wrapped/managed_ref_mut.rs | 10 ++++---- .../managed/wrapped/managed_vec_owned_iter.rs | 8 +++---- .../managed/wrapped/managed_vec_ref_iter.rs | 6 ++--- .../src/types/static_buffer/sparse_array.rs | 8 +++---- .../scenario/src/facade/expr/file_path.rs | 2 +- .../scenario/src/facade/expr/mxsc_path.rs | 8 +++---- .../scenario/src/facade/expr/num_expr.rs | 8 +++---- .../facade/result_handlers/expect_error.rs | 4 ++-- .../facade/result_handlers/expect_message.rs | 4 ++-- .../facade/world_tx/scenario_check_state.rs | 2 +- .../src/facade/world_tx/scenario_exec_call.rs | 8 +++---- .../facade/world_tx/scenario_query_call.rs | 4 ++-- .../src/facade/world_tx/scenario_set_state.rs | 4 ++-- .../scenario_set_account.rs | 2 +- .../scenario_set_state/scenario_set_block.rs | 2 +- 39 files changed, 102 insertions(+), 102 deletions(-) diff --git a/framework/base/src/hex_call_data/cd_de.rs b/framework/base/src/hex_call_data/cd_de.rs index ce6d6bdb63..f1826425e6 100644 --- a/framework/base/src/hex_call_data/cd_de.rs +++ b/framework/base/src/hex_call_data/cd_de.rs @@ -103,7 +103,7 @@ impl<'a> HexCallDataDeserializer<'a> { } } -impl<'a> TopDecodeMultiInput for HexCallDataDeserializer<'a> { +impl TopDecodeMultiInput for HexCallDataDeserializer<'_> { type ValueInput = Box<[u8]>; fn has_next(&self) -> bool { diff --git a/framework/base/src/storage/mappers/bi_di_mapper.rs b/framework/base/src/storage/mappers/bi_di_mapper.rs index ce0f24c159..decb892d2f 100644 --- a/framework/base/src/storage/mappers/bi_di_mapper.rs +++ b/framework/base/src/storage/mappers/bi_di_mapper.rs @@ -264,7 +264,7 @@ where } } -impl<'a, SA, K, V, A> Iterator for Iter<'a, SA, K, V, A> +impl Iterator for Iter<'_, SA, K, V, A> where SA: StorageMapperApi, A: StorageAddress, diff --git a/framework/base/src/storage/mappers/linked_list_mapper.rs b/framework/base/src/storage/mappers/linked_list_mapper.rs index a259467c29..0eba2da505 100644 --- a/framework/base/src/storage/mappers/linked_list_mapper.rs +++ b/framework/base/src/storage/mappers/linked_list_mapper.rs @@ -578,7 +578,7 @@ where } } -impl<'a, SA, T, A> Iterator for Iter<'a, SA, T, A> +impl Iterator for Iter<'_, SA, T, A> where SA: StorageMapperApi, A: StorageAddress, diff --git a/framework/base/src/storage/mappers/map_mapper.rs b/framework/base/src/storage/mappers/map_mapper.rs index 9e90917985..16cdf729fc 100644 --- a/framework/base/src/storage/mappers/map_mapper.rs +++ b/framework/base/src/storage/mappers/map_mapper.rs @@ -234,7 +234,7 @@ where } } -impl<'a, SA, A, K, V> Iterator for Iter<'a, SA, A, K, V> +impl Iterator for Iter<'_, SA, A, K, V> where SA: StorageMapperApi, A: StorageAddress, @@ -279,7 +279,7 @@ where } } -impl<'a, SA, A, K, V> Iterator for Values<'a, SA, A, K, V> +impl Iterator for Values<'_, SA, A, K, V> where SA: StorageMapperApi, A: StorageAddress, @@ -344,7 +344,7 @@ where pub(super) _marker: PhantomData<&'a mut (K, V)>, } -impl<'a, SA, A, K, V> Entry<'a, SA, A, K, V> +impl Entry<'_, SA, A, K, V> where SA: StorageMapperApi, A: StorageAddress, @@ -470,7 +470,7 @@ where } } -impl<'a, SA, A, K, V> OccupiedEntry<'a, SA, A, K, V> +impl OccupiedEntry<'_, SA, A, K, V> where SA: StorageMapperApi, A: StorageAddress, @@ -488,7 +488,7 @@ where } } -impl<'a, SA, K, V> OccupiedEntry<'a, SA, CurrentStorage, K, V> +impl OccupiedEntry<'_, SA, CurrentStorage, K, V> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, diff --git a/framework/base/src/storage/mappers/map_storage_mapper.rs b/framework/base/src/storage/mappers/map_storage_mapper.rs index 699a3bab36..ed368a1822 100644 --- a/framework/base/src/storage/mappers/map_storage_mapper.rs +++ b/framework/base/src/storage/mappers/map_storage_mapper.rs @@ -221,7 +221,7 @@ where } } -impl<'a, SA, A, K, V> Iterator for Iter<'a, SA, A, K, V> +impl Iterator for Iter<'_, SA, A, K, V> where SA: StorageMapperApi, A: StorageAddress, @@ -268,7 +268,7 @@ where } } -impl<'a, SA, A, K, V> Iterator for Values<'a, SA, A, K, V> +impl Iterator for Values<'_, SA, A, K, V> where SA: StorageMapperApi, A: StorageAddress, @@ -388,7 +388,7 @@ where } } -impl<'a, SA, A, K, V> VacantEntry<'a, SA, A, K, V> +impl VacantEntry<'_, SA, A, K, V> where SA: StorageMapperApi, A: StorageAddress, @@ -420,7 +420,7 @@ where } } -impl<'a, SA, A, K, V> OccupiedEntry<'a, SA, A, K, V> +impl OccupiedEntry<'_, SA, A, K, V> where SA: StorageMapperApi, A: StorageAddress, @@ -438,7 +438,7 @@ where } } -impl<'a, SA, K, V> OccupiedEntry<'a, SA, CurrentStorage, K, V> +impl OccupiedEntry<'_, SA, CurrentStorage, K, V> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static, diff --git a/framework/base/src/storage/mappers/queue_mapper.rs b/framework/base/src/storage/mappers/queue_mapper.rs index 9937736b01..80572d1b41 100644 --- a/framework/base/src/storage/mappers/queue_mapper.rs +++ b/framework/base/src/storage/mappers/queue_mapper.rs @@ -484,7 +484,7 @@ where } } -impl<'a, SA, A, T> Iterator for Iter<'a, SA, A, T> +impl Iterator for Iter<'_, SA, A, T> where SA: StorageMapperApi, A: StorageAddress, diff --git a/framework/base/src/storage/mappers/unique_id_mapper.rs b/framework/base/src/storage/mappers/unique_id_mapper.rs index a1789d695a..a8605963a1 100644 --- a/framework/base/src/storage/mappers/unique_id_mapper.rs +++ b/framework/base/src/storage/mappers/unique_id_mapper.rs @@ -180,7 +180,7 @@ where } } -impl<'a, SA, A> Iterator for Iter<'a, SA, A> +impl Iterator for Iter<'_, SA, A> where SA: StorageMapperApi, A: StorageAddress, diff --git a/framework/base/src/storage/mappers/vec_mapper.rs b/framework/base/src/storage/mappers/vec_mapper.rs index 22b8763ece..0b7eb4cb5d 100644 --- a/framework/base/src/storage/mappers/vec_mapper.rs +++ b/framework/base/src/storage/mappers/vec_mapper.rs @@ -320,7 +320,7 @@ where } } -impl<'a, SA, T, A> Iterator for Iter<'a, SA, T, A> +impl Iterator for Iter<'_, SA, T, A> where SA: StorageMapperApi, A: StorageAddress, diff --git a/framework/base/src/storage/storage_get.rs b/framework/base/src/storage/storage_get.rs index b33b5e1dcb..3cd6324aae 100644 --- a/framework/base/src/storage/storage_get.rs +++ b/framework/base/src/storage/storage_get.rs @@ -57,7 +57,7 @@ where } } -impl<'k, A> TopDecodeInput for StorageGetInput<'k, A> +impl TopDecodeInput for StorageGetInput<'_, A> where A: StorageReadApi + ManagedTypeApi + ErrorApi + 'static, { diff --git a/framework/base/src/storage/storage_get_from_address.rs b/framework/base/src/storage/storage_get_from_address.rs index 13a467d2f0..14b1bfabf0 100644 --- a/framework/base/src/storage/storage_get_from_address.rs +++ b/framework/base/src/storage/storage_get_from_address.rs @@ -66,7 +66,7 @@ where } } -impl<'k, A> TopDecodeInput for StorageGetFromAddressInput<'k, A> +impl TopDecodeInput for StorageGetFromAddressInput<'_, A> where A: StorageReadApi + ManagedTypeApi + ErrorApi + 'static, { diff --git a/framework/base/src/storage/storage_set.rs b/framework/base/src/storage/storage_set.rs index a2f3c3b722..8907b2abbf 100644 --- a/framework/base/src/storage/storage_set.rs +++ b/framework/base/src/storage/storage_set.rs @@ -37,7 +37,7 @@ where } } -impl<'k, A> TopEncodeOutput for StorageSetOutput<'k, A> +impl TopEncodeOutput for StorageSetOutput<'_, A> where A: StorageWriteApi + ManagedTypeApi + ErrorApi + 'static, { diff --git a/framework/base/src/types/interaction/annotated/annotated_impl_big_uint.rs b/framework/base/src/types/interaction/annotated/annotated_impl_big_uint.rs index f05952ab75..590e73545f 100644 --- a/framework/base/src/types/interaction/annotated/annotated_impl_big_uint.rs +++ b/framework/base/src/types/interaction/annotated/annotated_impl_big_uint.rs @@ -53,7 +53,7 @@ where } } -impl<'a, Env> AnnotatedValue> for ManagedRef<'a, Env::Api, BigUint> +impl AnnotatedValue> for ManagedRef<'_, Env::Api, BigUint> where Env: TxEnv, { diff --git a/framework/base/src/types/interaction/expr/test_address.rs b/framework/base/src/types/interaction/expr/test_address.rs index 01d1dc819d..ed348c4e9c 100644 --- a/framework/base/src/types/interaction/expr/test_address.rs +++ b/framework/base/src/types/interaction/expr/test_address.rs @@ -56,13 +56,13 @@ impl<'a> TestAddress<'a> { } } -impl<'a, 'b> PartialEq> for TestAddress<'a> { +impl PartialEq> for TestAddress<'_> { fn eq(&self, other: &TestSCAddress) -> bool { self.to_address() == other.to_address() } } -impl<'a> PartialEq

for TestAddress<'a> { +impl PartialEq
for TestAddress<'_> { fn eq(&self, other: &Address) -> bool { &self.to_address() == other } @@ -74,7 +74,7 @@ impl<'a> PartialEq> for Address { } } -impl<'a, Api: ManagedTypeApi> PartialEq> for TestAddress<'a> { +impl PartialEq> for TestAddress<'_> { fn eq(&self, other: &ManagedAddress) -> bool { self.to_address() == other.to_address() } @@ -86,7 +86,7 @@ impl<'a, Api: ManagedTypeApi> PartialEq> for ManagedAddress } } -impl<'a, Env> AnnotatedValue> for TestAddress<'a> +impl AnnotatedValue> for TestAddress<'_> where Env: TxEnv, { @@ -102,7 +102,7 @@ where } } -impl<'a, Env> TxFrom for TestAddress<'a> +impl TxFrom for TestAddress<'_> where Env: TxEnv, { @@ -111,11 +111,11 @@ where expr.into() } } -impl<'a, Env> TxFromSpecified for TestAddress<'a> where Env: TxEnv {} -impl<'a, Env> TxTo for TestAddress<'a> where Env: TxEnv {} -impl<'a, Env> TxToSpecified for TestAddress<'a> where Env: TxEnv {} +impl TxFromSpecified for TestAddress<'_> where Env: TxEnv {} +impl TxTo for TestAddress<'_> where Env: TxEnv {} +impl TxToSpecified for TestAddress<'_> where Env: TxEnv {} -impl<'a> TopEncode for TestAddress<'a> { +impl TopEncode for TestAddress<'_> { fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> where O: TopEncodeOutput, @@ -125,7 +125,7 @@ impl<'a> TopEncode for TestAddress<'a> { } } -impl<'a, Api> TypeAbiFrom> for ManagedAddress where Api: ManagedTypeApi {} +impl TypeAbiFrom> for ManagedAddress where Api: ManagedTypeApi {} #[cfg(test)] pub mod tests { diff --git a/framework/base/src/types/interaction/expr/test_sc_address.rs b/framework/base/src/types/interaction/expr/test_sc_address.rs index 564157fb94..520d3a6fc9 100644 --- a/framework/base/src/types/interaction/expr/test_sc_address.rs +++ b/framework/base/src/types/interaction/expr/test_sc_address.rs @@ -32,7 +32,7 @@ impl<'a> TestSCAddress<'a> { } } -impl<'a, Env> AnnotatedValue> for TestSCAddress<'a> +impl AnnotatedValue> for TestSCAddress<'_> where Env: TxEnv, { @@ -48,7 +48,7 @@ where } } -impl<'a> TestSCAddress<'a> { +impl TestSCAddress<'_> { pub fn to_address(&self) -> Address { self.eval_to_array().into() } @@ -58,13 +58,13 @@ impl<'a> TestSCAddress<'a> { } } -impl<'a, 'b> PartialEq> for TestSCAddress<'a> { +impl PartialEq> for TestSCAddress<'_> { fn eq(&self, other: &TestAddress) -> bool { self.to_address() == other.to_address() } } -impl<'a> PartialEq
for TestSCAddress<'a> { +impl PartialEq
for TestSCAddress<'_> { fn eq(&self, other: &Address) -> bool { &self.to_address() == other } @@ -76,7 +76,7 @@ impl<'a> PartialEq> for Address { } } -impl<'a, Api: ManagedTypeApi> PartialEq> for TestSCAddress<'a> { +impl PartialEq> for TestSCAddress<'_> { fn eq(&self, other: &ManagedAddress) -> bool { self.to_address() == other.to_address() } @@ -88,7 +88,7 @@ impl<'a, Api: ManagedTypeApi> PartialEq> for ManagedAddress TxFrom for TestSCAddress<'a> +impl TxFrom for TestSCAddress<'_> where Env: TxEnv, { @@ -97,11 +97,11 @@ where expr.into() } } -impl<'a, Env> TxFromSpecified for TestSCAddress<'a> where Env: TxEnv {} -impl<'a, Env> TxTo for TestSCAddress<'a> where Env: TxEnv {} -impl<'a, Env> TxToSpecified for TestSCAddress<'a> where Env: TxEnv {} +impl TxFromSpecified for TestSCAddress<'_> where Env: TxEnv {} +impl TxTo for TestSCAddress<'_> where Env: TxEnv {} +impl TxToSpecified for TestSCAddress<'_> where Env: TxEnv {} -impl<'a> TestSCAddress<'a> { +impl TestSCAddress<'_> { pub fn eval_to_array(&self) -> [u8; 32] { let result = *b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00______________________"; let expr_bytes = self.name.as_bytes(); @@ -130,7 +130,7 @@ impl<'a> TestSCAddress<'a> { } } -impl<'a> TopEncode for TestSCAddress<'a> { +impl TopEncode for TestSCAddress<'_> { fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> where O: TopEncodeOutput, @@ -140,7 +140,7 @@ impl<'a> TopEncode for TestSCAddress<'a> { } } -impl<'a, Api> TypeAbiFrom> for ManagedAddress where Api: ManagedTypeApi {} +impl TypeAbiFrom> for ManagedAddress where Api: ManagedTypeApi {} #[cfg(test)] pub mod tests { diff --git a/framework/base/src/types/interaction/expr/test_token_identifier.rs b/framework/base/src/types/interaction/expr/test_token_identifier.rs index 68865d8fbc..44a87988b2 100644 --- a/framework/base/src/types/interaction/expr/test_token_identifier.rs +++ b/framework/base/src/types/interaction/expr/test_token_identifier.rs @@ -40,7 +40,7 @@ impl<'a> TestTokenIdentifier<'a> { } } -impl<'a, Env> AnnotatedValue> for TestTokenIdentifier<'a> +impl AnnotatedValue> for TestTokenIdentifier<'_> where Env: TxEnv, { @@ -64,7 +64,7 @@ where } } -impl<'a> TopEncode for TestTokenIdentifier<'a> { +impl TopEncode for TestTokenIdentifier<'_> { fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> where O: TopEncodeOutput, @@ -74,5 +74,5 @@ impl<'a> TopEncode for TestTokenIdentifier<'a> { } } -impl<'a, Api> TypeAbiFrom> for TokenIdentifier where Api: ManagedTypeApi +impl TypeAbiFrom> for TokenIdentifier where Api: ManagedTypeApi {} diff --git a/framework/base/src/types/interaction/tx_payment/test_esdt_transfer.rs b/framework/base/src/types/interaction/tx_payment/test_esdt_transfer.rs index 99d00a219e..307bc06133 100644 --- a/framework/base/src/types/interaction/tx_payment/test_esdt_transfer.rs +++ b/framework/base/src/types/interaction/tx_payment/test_esdt_transfer.rs @@ -26,7 +26,7 @@ where } } -impl<'a, Env> TxPayment for TestEsdtTransfer<'a> +impl TxPayment for TestEsdtTransfer<'_> where Env: TxEnv, { diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_refs.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_refs.rs index 14f9058b55..1326974817 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_refs.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_refs.rs @@ -2,7 +2,7 @@ use crate::types::{BigUint, EgldOrEsdtTokenPaymentRefs, ManagedAddress, TxFrom, use super::{Egld, FullPaymentData, FunctionCall, TxEnv, TxPayment}; -impl<'a, Env> TxPayment for EgldOrEsdtTokenPaymentRefs<'a, Env::Api> +impl TxPayment for EgldOrEsdtTokenPaymentRefs<'_, Env::Api> where Env: TxEnv, { diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_multi_esdt_ref.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_multi_esdt_ref.rs index 9d4eb6c20a..8cd88504ae 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_multi_esdt_ref.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_multi_esdt_ref.rs @@ -2,7 +2,7 @@ use crate::types::{BigUint, EgldOrMultiEsdtPaymentRefs, ManagedAddress, TxFrom, use super::{Egld, FullPaymentData, FunctionCall, TxEnv, TxPayment}; -impl<'a, Env> TxPayment for EgldOrMultiEsdtPaymentRefs<'a, Env::Api> +impl TxPayment for EgldOrMultiEsdtPaymentRefs<'_, Env::Api> where Env: TxEnv, { diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_value.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_value.rs index 99d91b618f..9b32d93a4e 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_value.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_value.rs @@ -10,5 +10,5 @@ where impl TxEgldValue for BigUint where Env: TxEnv {} impl TxEgldValue for &BigUint where Env: TxEnv {} -impl<'a, Env> TxEgldValue for ManagedRef<'a, Env::Api, BigUint> where Env: TxEnv {} +impl TxEgldValue for ManagedRef<'_, Env::Api, BigUint> where Env: TxEnv {} impl TxEgldValue for u64 where Env: TxEnv {} 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 c0afc2055c..ab030362d2 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 @@ -16,7 +16,7 @@ where impl TxPaymentMultiEsdt for MultiEsdtPayment where Env: TxEnv {} impl TxPaymentMultiEsdt for &MultiEsdtPayment where Env: TxEnv {} -impl<'a, Env> TxPaymentMultiEsdt for ManagedRef<'a, Env::Api, MultiEsdtPayment> where +impl TxPaymentMultiEsdt for ManagedRef<'_, Env::Api, MultiEsdtPayment> where Env: TxEnv { } @@ -76,7 +76,7 @@ where } } -impl<'a, Env> TxPayment for ManagedRef<'a, Env::Api, MultiEsdtPayment> +impl TxPayment for ManagedRef<'_, Env::Api, MultiEsdtPayment> where Env: TxEnv, { diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_ref.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_ref.rs index c91391d316..6aecb277a6 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_ref.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_ref.rs @@ -7,7 +7,7 @@ use crate::{ use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; -impl<'a, Env> TxPayment for EsdtTokenPaymentRefs<'a, Env::Api> +impl TxPayment for EsdtTokenPaymentRefs<'_, Env::Api> where Env: TxEnv, { diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index 66dd7c9ec9..0bffac57a3 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -207,11 +207,11 @@ impl TypeAbiFrom<&TokenIdentifier> for EgldOrEsdtTokenIdentifier where impl TypeAbiFrom<&[u8]> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} impl TypeAbiFrom<&str> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} -impl<'a, M> TypeAbiFrom> for EgldOrEsdtTokenIdentifier where +impl TypeAbiFrom> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi { } -impl<'a, M> TypeAbiFrom<&TestTokenIdentifier<'a>> for EgldOrEsdtTokenIdentifier where +impl TypeAbiFrom<&TestTokenIdentifier<'_>> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi { } diff --git a/framework/base/src/types/managed/wrapped/egld_or_multi_esdt_payment.rs b/framework/base/src/types/managed/wrapped/egld_or_multi_esdt_payment.rs index 88534f95c1..1c06f0677c 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_multi_esdt_payment.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_multi_esdt_payment.rs @@ -49,7 +49,7 @@ impl EgldOrMultiEsdtPayment { } } -impl<'a, M: ManagedTypeApi> EgldOrMultiEsdtPaymentRefs<'a, M> { +impl EgldOrMultiEsdtPaymentRefs<'_, M> { pub fn to_owned_payment(&self) -> EgldOrMultiEsdtPayment { match self { EgldOrMultiEsdtPaymentRefs::Egld(egld_value) => { diff --git a/framework/base/src/types/managed/wrapped/managed_ref.rs b/framework/base/src/types/managed/wrapped/managed_ref.rs index f618063b3c..efdf4a9596 100644 --- a/framework/base/src/types/managed/wrapped/managed_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_ref.rs @@ -49,7 +49,7 @@ where } } -impl<'a, M, T> ManagedRef<'a, M, T> +impl ManagedRef<'_, M, T> where M: ManagedTypeApi, T: ManagedType + Clone, @@ -60,7 +60,7 @@ where } } -impl<'a, M, T> Clone for ManagedRef<'a, M, T> +impl Clone for ManagedRef<'_, M, T> where M: ManagedTypeApi, T: ManagedType, @@ -75,7 +75,7 @@ where } } -impl<'a, M, T> Deref for ManagedRef<'a, M, T> +impl Deref for ManagedRef<'_, M, T> where M: ManagedTypeApi, T: ManagedType, @@ -88,7 +88,7 @@ where } } -impl<'a, M, T> Borrow for ManagedRef<'a, M, T> +impl Borrow for ManagedRef<'_, M, T> where M: ManagedTypeApi, T: ManagedType, @@ -110,7 +110,7 @@ where } } -impl<'a, M, T> PartialEq for ManagedRef<'a, M, T> +impl PartialEq for ManagedRef<'_, M, T> where M: ManagedTypeApi, T: ManagedType + PartialEq, @@ -121,14 +121,14 @@ where } } -impl<'a, M, T> Eq for ManagedRef<'a, M, T> +impl Eq for ManagedRef<'_, M, T> where M: ManagedTypeApi, T: ManagedType + PartialEq, { } -impl<'a, M, T> TopEncode for ManagedRef<'a, M, T> +impl TopEncode for ManagedRef<'_, M, T> where M: ManagedTypeApi, T: ManagedType + TopEncode, diff --git a/framework/base/src/types/managed/wrapped/managed_ref_mut.rs b/framework/base/src/types/managed/wrapped/managed_ref_mut.rs index 868ef89e78..e017021d24 100644 --- a/framework/base/src/types/managed/wrapped/managed_ref_mut.rs +++ b/framework/base/src/types/managed/wrapped/managed_ref_mut.rs @@ -115,7 +115,7 @@ where } } -impl<'a, M, T> PartialEq for ManagedRefMut<'a, M, T> +impl PartialEq for ManagedRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedType + PartialEq, @@ -126,14 +126,14 @@ where } } -impl<'a, M, T> Eq for ManagedRefMut<'a, M, T> +impl Eq for ManagedRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedType + PartialEq, { } -impl<'a, M, T> TopEncode for ManagedRefMut<'a, M, T> +impl TopEncode for ManagedRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedType + TopEncode, @@ -148,7 +148,7 @@ where } } -impl<'a, M, T> NestedEncode for ManagedRefMut<'a, M, T> +impl NestedEncode for ManagedRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedType + NestedEncode, @@ -163,7 +163,7 @@ where } } -impl<'a, M, T> core::fmt::Debug for ManagedRefMut<'a, M, T> +impl core::fmt::Debug for ManagedRefMut<'_, M, T> where M: ManagedTypeApi, T: ManagedType + core::fmt::Debug, diff --git a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs index 8e0da8727c..b5e342d345 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs @@ -39,7 +39,7 @@ where } } -impl<'a, M, T> Iterator for ManagedVecOwnedIterator<'a, M, T> +impl Iterator for ManagedVecOwnedIterator<'_, M, T> where M: ManagedTypeApi, T: ManagedVecItem, @@ -70,14 +70,14 @@ where } } -impl<'a, M, T> ExactSizeIterator for ManagedVecOwnedIterator<'a, M, T> +impl ExactSizeIterator for ManagedVecOwnedIterator<'_, M, T> where M: ManagedTypeApi, T: ManagedVecItem, { } -impl<'a, M, T> DoubleEndedIterator for ManagedVecOwnedIterator<'a, M, T> +impl DoubleEndedIterator for ManagedVecOwnedIterator<'_, M, T> where M: ManagedTypeApi, T: ManagedVecItem, @@ -98,7 +98,7 @@ where } } -impl<'a, M, T> Clone for ManagedVecOwnedIterator<'a, M, T> +impl Clone for ManagedVecOwnedIterator<'_, M, T> where M: ManagedTypeApi, T: ManagedVecItem, diff --git a/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs index 4703a1f61b..18cfcf84fe 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs @@ -56,14 +56,14 @@ where } } -impl<'a, M, T> ExactSizeIterator for ManagedVecRefIterator<'a, M, T> +impl ExactSizeIterator for ManagedVecRefIterator<'_, M, T> where M: ManagedTypeApi, T: ManagedVecItem, { } -impl<'a, M, T> DoubleEndedIterator for ManagedVecRefIterator<'a, M, T> +impl DoubleEndedIterator for ManagedVecRefIterator<'_, M, T> where M: ManagedTypeApi, T: ManagedVecItem, @@ -84,7 +84,7 @@ where } } -impl<'a, M, T> Clone for ManagedVecRefIterator<'a, M, T> +impl Clone for ManagedVecRefIterator<'_, M, T> where M: ManagedTypeApi, T: ManagedVecItem, diff --git a/framework/base/src/types/static_buffer/sparse_array.rs b/framework/base/src/types/static_buffer/sparse_array.rs index bb3a083243..911069a73d 100644 --- a/framework/base/src/types/static_buffer/sparse_array.rs +++ b/framework/base/src/types/static_buffer/sparse_array.rs @@ -156,7 +156,7 @@ where } } -impl<'a, E, const CAPACITY: usize> Iterator for SparseArrayIterator<'a, E, CAPACITY> +impl Iterator for SparseArrayIterator<'_, E, CAPACITY> where E: ErrorApi, { @@ -179,12 +179,12 @@ where } } -impl<'a, E, const CAPACITY: usize> ExactSizeIterator for SparseArrayIterator<'a, E, CAPACITY> where +impl ExactSizeIterator for SparseArrayIterator<'_, E, CAPACITY> where E: ErrorApi { } -impl<'a, E, const CAPACITY: usize> DoubleEndedIterator for SparseArrayIterator<'a, E, CAPACITY> +impl DoubleEndedIterator for SparseArrayIterator<'_, E, CAPACITY> where E: ErrorApi, { @@ -200,7 +200,7 @@ where } } -impl<'a, E, const CAPACITY: usize> Clone for SparseArrayIterator<'a, E, CAPACITY> +impl Clone for SparseArrayIterator<'_, E, CAPACITY> where E: ErrorApi, { diff --git a/framework/scenario/src/facade/expr/file_path.rs b/framework/scenario/src/facade/expr/file_path.rs index 0c05165fb2..593610ecd6 100644 --- a/framework/scenario/src/facade/expr/file_path.rs +++ b/framework/scenario/src/facade/expr/file_path.rs @@ -22,7 +22,7 @@ impl FilePath<'_> { } } -impl<'a, Env> AnnotatedValue> for FilePath<'a> +impl AnnotatedValue> for FilePath<'_> where Env: ScenarioTxEnv, { diff --git a/framework/scenario/src/facade/expr/mxsc_path.rs b/framework/scenario/src/facade/expr/mxsc_path.rs index 465eb5f097..fac10d6a46 100644 --- a/framework/scenario/src/facade/expr/mxsc_path.rs +++ b/framework/scenario/src/facade/expr/mxsc_path.rs @@ -20,7 +20,7 @@ impl<'a> MxscPath<'a> { } } -impl<'a> MxscPath<'a> { +impl MxscPath<'_> { pub fn eval_to_expr(&self) -> String { format!("{MXSC_PREFIX}{}", self.path) } @@ -30,7 +30,7 @@ impl<'a> MxscPath<'a> { } } -impl<'a, Env> AnnotatedValue> for MxscPath<'a> +impl AnnotatedValue> for MxscPath<'_> where Env: ScenarioTxEnv, { @@ -44,9 +44,9 @@ where } } -impl<'a, Env> TxCodeValue for MxscPath<'a> where Env: ScenarioTxEnv {} +impl TxCodeValue for MxscPath<'_> where Env: ScenarioTxEnv {} -impl<'a> RegisterCodeSource for MxscPath<'a> { +impl RegisterCodeSource for MxscPath<'_> { fn into_code(self, env_data: ScenarioTxEnvData) -> Vec { self.resolve_contents(&env_data.interpreter_context()) } diff --git a/framework/scenario/src/facade/expr/num_expr.rs b/framework/scenario/src/facade/expr/num_expr.rs index 704f52496b..55a849c1d3 100644 --- a/framework/scenario/src/facade/expr/num_expr.rs +++ b/framework/scenario/src/facade/expr/num_expr.rs @@ -19,7 +19,7 @@ where BigUint::from_bytes_be(&bytes) } -impl<'a, Env> AnnotatedValue> for NumExpr<'a> +impl AnnotatedValue> for NumExpr<'_> where Env: ScenarioTxEnv, { @@ -32,7 +32,7 @@ where } } -impl<'a, Env> AnnotatedValue for NumExpr<'a> +impl AnnotatedValue for NumExpr<'_> where Env: ScenarioTxEnv, { @@ -45,5 +45,5 @@ where } } -impl<'a, Env> TxEgldValue for NumExpr<'a> where Env: ScenarioTxEnv {} -impl<'a, Env> TxGasValue for NumExpr<'a> where Env: ScenarioTxEnv {} +impl TxEgldValue for NumExpr<'_> where Env: ScenarioTxEnv {} +impl TxGasValue for NumExpr<'_> where Env: ScenarioTxEnv {} diff --git a/framework/scenario/src/facade/result_handlers/expect_error.rs b/framework/scenario/src/facade/result_handlers/expect_error.rs index a06a227424..55e2bde473 100644 --- a/framework/scenario/src/facade/result_handlers/expect_error.rs +++ b/framework/scenario/src/facade/result_handlers/expect_error.rs @@ -8,14 +8,14 @@ use crate::scenario_model::{BytesValue, CheckValue, TxExpect, TxResponse}; /// Can only be used in tests and interactors, not available in contracts. pub struct ExpectError<'a>(pub u64, pub &'a str); -impl<'a, Env, Original> RHListItem for ExpectError<'a> +impl RHListItem for ExpectError<'_> where Env: TxEnv, { type Returns = (); } -impl<'a, Env, Original> RHListItemExec for ExpectError<'a> +impl RHListItemExec for ExpectError<'_> where Env: TxEnv, { diff --git a/framework/scenario/src/facade/result_handlers/expect_message.rs b/framework/scenario/src/facade/result_handlers/expect_message.rs index af5fa2a429..65f412fadd 100644 --- a/framework/scenario/src/facade/result_handlers/expect_message.rs +++ b/framework/scenario/src/facade/result_handlers/expect_message.rs @@ -8,14 +8,14 @@ use crate::scenario_model::{BytesValue, CheckValue, TxExpect, TxResponse, U64Val /// Can only be used in tests and interactors, not available in contracts. pub struct ExpectMessage<'a>(pub &'a str); -impl<'a, Env, Original> RHListItem for ExpectMessage<'a> +impl RHListItem for ExpectMessage<'_> where Env: TxEnv, { type Returns = (); } -impl<'a, Env, Original> RHListItemExec for ExpectMessage<'a> +impl RHListItemExec for ExpectMessage<'_> where Env: TxEnv, { diff --git a/framework/scenario/src/facade/world_tx/scenario_check_state.rs b/framework/scenario/src/facade/world_tx/scenario_check_state.rs index 3f5423419a..182edee26a 100644 --- a/framework/scenario/src/facade/world_tx/scenario_check_state.rs +++ b/framework/scenario/src/facade/world_tx/scenario_check_state.rs @@ -230,7 +230,7 @@ impl<'w> CheckStateBuilder<'w> { } } -impl<'w> Drop for CheckStateBuilder<'w> { +impl Drop for CheckStateBuilder<'_> { fn drop(&mut self) { self.commit_accounts(); } diff --git a/framework/scenario/src/facade/world_tx/scenario_exec_call.rs b/framework/scenario/src/facade/world_tx/scenario_exec_call.rs index 9c1551111b..a856d16d91 100644 --- a/framework/scenario/src/facade/world_tx/scenario_exec_call.rs +++ b/framework/scenario/src/facade/world_tx/scenario_exec_call.rs @@ -23,7 +23,7 @@ pub struct ScenarioEnvExec<'w> { pub data: ScenarioTxEnvData, } -impl<'w> TxEnv for ScenarioEnvExec<'w> { +impl TxEnv for ScenarioEnvExec<'_> { type Api = StaticApi; type RHExpect = TxExpect; @@ -41,7 +41,7 @@ impl<'w> TxEnv for ScenarioEnvExec<'w> { } } -impl<'w> TxEnvMockDeployAddress for ScenarioEnvExec<'w> { +impl TxEnvMockDeployAddress for ScenarioEnvExec<'_> { fn mock_deploy_new_address(&mut self, from: &From, new_address: NA) where From: TxFromSpecified, @@ -65,7 +65,7 @@ impl<'w> TxEnvMockDeployAddress for ScenarioEnvExec<'w> { } } -impl<'w> ScenarioTxEnv for ScenarioEnvExec<'w> { +impl ScenarioTxEnv for ScenarioEnvExec<'_> { fn env_data(&self) -> &ScenarioTxEnvData { &self.data } @@ -115,7 +115,7 @@ where } } -impl<'w> TxEnvWithTxHash for ScenarioEnvExec<'w> { +impl TxEnvWithTxHash for ScenarioEnvExec<'_> { fn set_tx_hash(&mut self, tx_hash: H256) { self.data.set_tx_hash(tx_hash); } diff --git a/framework/scenario/src/facade/world_tx/scenario_query_call.rs b/framework/scenario/src/facade/world_tx/scenario_query_call.rs index dc416439b4..afae3d80e9 100644 --- a/framework/scenario/src/facade/world_tx/scenario_query_call.rs +++ b/framework/scenario/src/facade/world_tx/scenario_query_call.rs @@ -18,7 +18,7 @@ pub struct ScenarioEnvQuery<'w> { pub data: ScenarioTxEnvData, } -impl<'w> TxEnv for ScenarioEnvQuery<'w> { +impl TxEnv for ScenarioEnvQuery<'_> { type Api = StaticApi; type RHExpect = TxExpect; @@ -36,7 +36,7 @@ impl<'w> TxEnv for ScenarioEnvQuery<'w> { } } -impl<'w> ScenarioTxEnv for ScenarioEnvQuery<'w> { +impl ScenarioTxEnv for ScenarioEnvQuery<'_> { fn env_data(&self) -> &ScenarioTxEnvData { &self.data } diff --git a/framework/scenario/src/facade/world_tx/scenario_set_state.rs b/framework/scenario/src/facade/world_tx/scenario_set_state.rs index 3fd44d70b3..ef256453f7 100644 --- a/framework/scenario/src/facade/world_tx/scenario_set_state.rs +++ b/framework/scenario/src/facade/world_tx/scenario_set_state.rs @@ -239,7 +239,7 @@ impl<'w> SetStateBuilderBase<'w> { } } -impl<'w> SetStateBuilder<'w, ()> {} +impl SetStateBuilder<'_, ()> {} impl<'w, Item> SetStateBuilder<'w, Item> where @@ -313,7 +313,7 @@ where pub fn commit(self) {} } -impl<'w, Current> Drop for SetStateBuilder<'w, Current> +impl Drop for SetStateBuilder<'_, Current> where Current: SetStateBuilderItem, { diff --git a/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_account.rs b/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_account.rs index f5590894e1..a9821659a5 100644 --- a/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_account.rs +++ b/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_account.rs @@ -38,7 +38,7 @@ impl SetStateBuilderItem for AccountItem { } } -impl<'w> SetStateBuilder<'w, AccountItem> { +impl SetStateBuilder<'_, AccountItem> { pub fn nonce(mut self, nonce: N) -> Self where N: AnnotatedValue, diff --git a/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_block.rs b/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_block.rs index 3ef0d06cca..e2244207db 100644 --- a/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_block.rs +++ b/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_block.rs @@ -49,7 +49,7 @@ impl SetStateBuilderItem for BlockItem { } } -impl<'w> SetStateBuilder<'w, BlockItem> { +impl SetStateBuilder<'_, BlockItem> { pub fn block_epoch(mut self, block_epoch: N) -> Self where N: AnnotatedValue, From 205e4347c82917632a3faef372cf1f7e1371d1f5 Mon Sep 17 00:00:00 2001 From: Alin Cruceat Date: Fri, 29 Nov 2024 13:30:52 +0200 Subject: [PATCH 045/133] cargo fmt --- .../src/types/interaction/expr/test_token_identifier.rs | 3 +-- .../types/managed/wrapped/egld_or_esdt_token_identifier.rs | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/framework/base/src/types/interaction/expr/test_token_identifier.rs b/framework/base/src/types/interaction/expr/test_token_identifier.rs index 44a87988b2..36ee135239 100644 --- a/framework/base/src/types/interaction/expr/test_token_identifier.rs +++ b/framework/base/src/types/interaction/expr/test_token_identifier.rs @@ -74,5 +74,4 @@ impl TopEncode for TestTokenIdentifier<'_> { } } -impl TypeAbiFrom> for TokenIdentifier where Api: ManagedTypeApi -{} +impl TypeAbiFrom> for TokenIdentifier where Api: ManagedTypeApi {} diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index 0bffac57a3..7b46cb2e50 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -207,10 +207,8 @@ impl TypeAbiFrom<&TokenIdentifier> for EgldOrEsdtTokenIdentifier where impl TypeAbiFrom<&[u8]> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} impl TypeAbiFrom<&str> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} -impl TypeAbiFrom> for EgldOrEsdtTokenIdentifier where - M: ManagedTypeApi -{ -} +impl TypeAbiFrom> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi +{} impl TypeAbiFrom<&TestTokenIdentifier<'_>> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi { From 10f2939d7405c038c03d90b5793f483ff0451dfc Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Fri, 29 Nov 2024 14:47:16 +0200 Subject: [PATCH 046/133] test - multi transfer with egld --- .../interact/src/bf_interact.rs | 52 +++++++++++++++ .../interact/tests/bf_interact_cs_test.rs | 1 + .../multi_transfer_with_egld.scen.json | 66 +++++++++++++++++++ .../tests/basic_features_scenario_go_test.rs | 5 ++ .../tests/basic_features_scenario_rs_test.rs | 6 ++ 5 files changed, 130 insertions(+) create mode 100644 contracts/feature-tests/basic-features/scenarios/multi_transfer_with_egld.scen.json diff --git a/contracts/feature-tests/basic-features/interact/src/bf_interact.rs b/contracts/feature-tests/basic-features/interact/src/bf_interact.rs index 665fa24fc8..85c0cf8abd 100644 --- a/contracts/feature-tests/basic-features/interact/src/bf_interact.rs +++ b/contracts/feature-tests/basic-features/interact/src/bf_interact.rs @@ -306,4 +306,56 @@ impl BasicFeaturesInteract { }, } } + + pub async fn multi_transfer_with_egld(&mut self) { + let alice = self.interactor.register_wallet(test_wallets::alice()).await; + + let mut payments = ManagedVec::from(( + TokenIdentifier::from_esdt_bytes(b"EGLD-000000").clone(), + 0, + BigUint::from(50000000000000000u64), + )); + + let token = self + .interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .issue_fungible( + BigUint::from(50000000000000000u64), + "test", + "TEST", + BigUint::from(100usize), + FungibleTokenProperties { + num_decimals: 0usize, + can_freeze: true, + can_wipe: true, + can_pause: true, + can_mint: true, + can_burn: true, + can_change_owner: true, + can_upgrade: true, + can_add_special_roles: true, + }, + ) + .returns(ReturnsNewTokenIdentifier) + .run() + .await; + + payments.push(EsdtTokenPayment::new( + TokenIdentifier::from_esdt_bytes(token).clone(), + 0, + BigUint::from(10u32), + )); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(alice) + .payment(payments) + .run() + .await; + } } diff --git a/contracts/feature-tests/basic-features/interact/tests/bf_interact_cs_test.rs b/contracts/feature-tests/basic-features/interact/tests/bf_interact_cs_test.rs index 57702b5160..e9b3d70b74 100644 --- a/contracts/feature-tests/basic-features/interact/tests/bf_interact_cs_test.rs +++ b/contracts/feature-tests/basic-features/interact/tests/bf_interact_cs_test.rs @@ -16,6 +16,7 @@ async fn simulator_basic_features_test() { assert_eq!(bf_interact.large_storage_payload, data); bf_interact.deploy().await; + bf_interact.multi_transfer_with_egld().await; let expected_return_egld_decimal = ManagedDecimal::>::const_decimals_from_raw(BigUint::from( diff --git a/contracts/feature-tests/basic-features/scenarios/multi_transfer_with_egld.scen.json b/contracts/feature-tests/basic-features/scenarios/multi_transfer_with_egld.scen.json new file mode 100644 index 0000000000..92205812ee --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/multi_transfer_with_egld.scen.json @@ -0,0 +1,66 @@ +{ + "steps": [ + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-6bb410" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "bech32:erd1y3z4vsn2m026glevhsqpwrc5w4v0xzr2qmukc5qde39jnzze324qf4e2r4", + "to": "bech32:erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "egldValue": "50000000000000000", + "function": "issue", + "arguments": [ + "0x74657374", + "0x54455354", + "0x64", + "0x", + "0x63616e467265657a65", + "0x74727565", + "0x63616e57697065", + "0x74727565", + "0x63616e5061757365", + "0x74727565", + "0x63616e4d696e74", + "0x74727565", + "0x63616e4275726e", + "0x74727565", + "0x63616e4368616e67654f776e6572", + "0x74727565", + "0x63616e55706772616465", + "0x74727565", + "0x63616e4164645370656369616c526f6c6573", + "0x74727565" + ], + "gasLimit": "100000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "transfer", + "id": "", + "tx": { + "from": "bech32:erd1y3z4vsn2m026glevhsqpwrc5w4v0xzr2qmukc5qde39jnzze324qf4e2r4", + "to": "bech32:erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "esdtValue": [ + { + "tokenIdentifier": "0x45474c442d303030303030", + "value": "50000000000000000" + }, + { + "tokenIdentifier": "0x544553542d366262343130", + "value": "10" + } + ], + "gasLimit": "5,000,000" + } + } + ] +} diff --git a/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs index 02032a2126..b1717b0efc 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs @@ -187,6 +187,11 @@ fn echo_u_64_go() { world().run("scenarios/echo_u64.scen.json"); } +#[test] +fn multi_transfer_with_egld_go() { + world().run("scenarios/multi_transfer_with_egld.scen.json"); +} + #[test] fn echo_usize_go() { world().run("scenarios/echo_usize.scen.json"); diff --git a/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs index a4efa924ab..3268f63771 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs @@ -207,6 +207,12 @@ fn echo_u_64_rs() { world().run("scenarios/echo_u64.scen.json"); } +#[test] +#[ignore = "not supported yet"] +fn multi_transfer_with_egld_go() { + world().run("scenarios/multi_transfer_with_egld.scen.json"); +} + #[test] fn echo_usize_rs() { world().run("scenarios/echo_usize.scen.json"); From 5bfad3b2a14298c74d0489cbf2b8bb4d95527e54 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Fri, 29 Nov 2024 15:27:06 +0200 Subject: [PATCH 047/133] fix .scen.json test --- .../multi_transfer_with_egld.scen.json | 88 ++++++++++--------- .../tests/basic_features_scenario_rs_test.rs | 2 +- 2 files changed, 48 insertions(+), 42 deletions(-) diff --git a/contracts/feature-tests/basic-features/scenarios/multi_transfer_with_egld.scen.json b/contracts/feature-tests/basic-features/scenarios/multi_transfer_with_egld.scen.json index 92205812ee..0dcd2bfc6d 100644 --- a/contracts/feature-tests/basic-features/scenarios/multi_transfer_with_egld.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/multi_transfer_with_egld.scen.json @@ -2,45 +2,30 @@ "steps": [ { "step": "setState", - "newTokenIdentifiers": [ - "TEST-6bb410" - ] - }, - { - "step": "scCall", - "id": "", - "tx": { - "from": "bech32:erd1y3z4vsn2m026glevhsqpwrc5w4v0xzr2qmukc5qde39jnzze324qf4e2r4", - "to": "bech32:erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "egldValue": "50000000000000000", - "function": "issue", - "arguments": [ - "0x74657374", - "0x54455354", - "0x64", - "0x", - "0x63616e467265657a65", - "0x74727565", - "0x63616e57697065", - "0x74727565", - "0x63616e5061757365", - "0x74727565", - "0x63616e4d696e74", - "0x74727565", - "0x63616e4275726e", - "0x74727565", - "0x63616e4368616e67654f776e6572", - "0x74727565", - "0x63616e55706772616465", - "0x74727565", - "0x63616e4164645370656369616c526f6c6573", - "0x74727565" - ], - "gasLimit": "100000000" - }, - "expect": { - "out": [], - "status": "0" + "accounts": { + "bech32:erd1y3z4vsn2m026glevhsqpwrc5w4v0xzr2qmukc5qde39jnzze324qf4e2r4": { + "nonce": "0", + "balance": "10", + "esdt": { + "str:TEST-6bb410": { + "instances": [ + { + "nonce": "0", + "balance": "100", + "royalties": "0", + "attributes": "0x" + } + ] + } + }, + "developerRewards": "0" + }, + "bech32:erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa": { + "nonce": "0", + "balance": "0", + "esdt": {}, + "developerRewards": "0" + } } }, { @@ -52,7 +37,7 @@ "esdtValue": [ { "tokenIdentifier": "0x45474c442d303030303030", - "value": "50000000000000000" + "value": "4" }, { "tokenIdentifier": "0x544553542d366262343130", @@ -61,6 +46,27 @@ ], "gasLimit": "5,000,000" } + }, + { + "step": "checkState", + "accounts": { + "bech32:erd1y3z4vsn2m026glevhsqpwrc5w4v0xzr2qmukc5qde39jnzze324qf4e2r4": { + "nonce": "*", + "balance": "6", + "esdt": { + "str:TEST-6bb410": "90" + }, + "storage": {} + }, + "bech32:erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa": { + "nonce": "*", + "balance": "4", + "esdt": { + "str:TEST-6bb410": "10" + }, + "storage": {} + } + } } ] -} +} \ No newline at end of file diff --git a/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs index 3268f63771..0ab2459561 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs @@ -209,7 +209,7 @@ fn echo_u_64_rs() { #[test] #[ignore = "not supported yet"] -fn multi_transfer_with_egld_go() { +fn multi_transfer_with_egld_rs() { world().run("scenarios/multi_transfer_with_egld.scen.json"); } From 05ddbbc97df09ae25bc6a0b9a204f71b36d21862 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 29 Nov 2024 15:52:27 +0200 Subject: [PATCH 048/133] ManagedVec - iterator cleanup (ref vs. owned) --- .../examples/lottery-esdt/src/lottery.rs | 2 +- .../examples/multisig/src/multisig_state.rs | 3 ++- .../examples/order-book/pair/src/common.rs | 2 +- .../examples/order-book/pair/src/events.rs | 2 +- .../seed-nft-minter/src/seed_nft_minter.rs | 2 +- .../first-contract/src/lib.rs | 4 ++-- .../forwarder-raw/src/forwarder_raw.rs | 2 +- .../composability/vault/src/vault.rs | 2 +- contracts/modules/src/staking.rs | 2 +- framework/base/src/types/heap/arg_buffer.rs | 2 +- .../types/interaction/managed_arg_buffer.rs | 2 +- .../esdt_token_payment_multi_value.rs | 3 ++- .../multi_value/multi_value_encoded.rs | 21 +++------------- .../multi_value_encoded_counted.rs | 4 ++-- .../multi_value/multi_value_managed_vec.rs | 6 +++-- .../multi_value_managed_vec_counted.rs | 6 +++-- .../src/types/managed/wrapped/managed_ref.rs | 6 ++--- .../src/types/managed/wrapped/managed_vec.rs | 9 +++---- .../managed/wrapped/managed_vec_owned_iter.rs | 24 +++++++++---------- .../types/managed/wrapped/managed_vec_ref.rs | 5 ++++ .../managed/wrapped/managed_vec_ref_iter.rs | 12 ++++++++++ .../types/managed/wrapped/traits/mergeable.rs | 2 +- framework/scenario/tests/managed_ref_test.rs | 4 ++-- 23 files changed, 68 insertions(+), 59 deletions(-) diff --git a/contracts/examples/lottery-esdt/src/lottery.rs b/contracts/examples/lottery-esdt/src/lottery.rs index 3c5d9040b1..5c573ef651 100644 --- a/contracts/examples/lottery-esdt/src/lottery.rs +++ b/contracts/examples/lottery-esdt/src/lottery.rs @@ -148,7 +148,7 @@ pub trait Lottery { if let Some(whitelist) = opt_whitelist.as_option() { let mut mapper = self.lottery_whitelist(&lottery_name); for addr in &*whitelist { - mapper.insert(addr); + mapper.insert(addr.clone()); } } diff --git a/contracts/examples/multisig/src/multisig_state.rs b/contracts/examples/multisig/src/multisig_state.rs index bfadd8efd6..bd9002f770 100644 --- a/contracts/examples/multisig/src/multisig_state.rs +++ b/contracts/examples/multisig/src/multisig_state.rs @@ -37,6 +37,7 @@ pub trait MultisigStateModule { fn add_multiple_board_members(&self, new_board_members: ManagedVec) -> usize { let mut duplicates = false; + let new_board_members_len = new_board_members.len(); self.user_mapper().get_or_create_users( new_board_members.into_iter(), |user_id, new_user| { @@ -49,7 +50,7 @@ pub trait MultisigStateModule { require!(!duplicates, "duplicate board member"); let num_board_members_mapper = self.num_board_members(); - let new_num_board_members = num_board_members_mapper.get() + new_board_members.len(); + let new_num_board_members = num_board_members_mapper.get() + new_board_members_len; num_board_members_mapper.set(new_num_board_members); new_num_board_members diff --git a/contracts/examples/order-book/pair/src/common.rs b/contracts/examples/order-book/pair/src/common.rs index 85b1c1bca8..ce28101992 100644 --- a/contracts/examples/order-book/pair/src/common.rs +++ b/contracts/examples/order-book/pair/src/common.rs @@ -8,7 +8,7 @@ pub const FREE_ORDER_FROM_STORAGE_MIN_PENALTIES: u64 = 6; #[type_abi] #[derive( - ManagedVecItem, TopEncode, TopDecode, NestedEncode, NestedDecode, PartialEq, Eq, Clone, Copy + ManagedVecItem, TopEncode, TopDecode, NestedEncode, NestedDecode, PartialEq, Eq, Clone, Copy, )] pub enum OrderType { Buy, diff --git a/contracts/examples/order-book/pair/src/events.rs b/contracts/examples/order-book/pair/src/events.rs index f20331f44f..6b66feb37d 100644 --- a/contracts/examples/order-book/pair/src/events.rs +++ b/contracts/examples/order-book/pair/src/events.rs @@ -7,7 +7,7 @@ pub trait EventsModule { fn emit_order_event(&self, order: Order) { let caller = self.blockchain().get_caller(); let epoch = self.blockchain().get_block_epoch(); - let order_type = order.order_type.clone(); + let order_type = order.order_type; self.order_event(caller, epoch, order_type, order); } diff --git a/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs b/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs index f0cff643c6..510212891b 100644 --- a/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs +++ b/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs @@ -27,7 +27,7 @@ pub trait SeedNftMinter: marketplaces: ManagedVec, distribution: ManagedVec>, ) { - self.marketplaces().extend(&marketplaces); + self.marketplaces().extend(marketplaces); self.init_distribution(distribution); } diff --git a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs index 2d35ac5ea8..bf77e7ab4e 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs +++ b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs @@ -132,8 +132,8 @@ pub trait FirstContract { arg_buffer.push_arg(esdt_token_identifier); arg_buffer.push_arg(amount); arg_buffer.push_arg(func_name); - for arg in args.into_iter() { - arg_buffer.push_arg_raw(arg); + for arg in args { + arg_buffer.push_arg_raw(arg.clone()); } self.tx() diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs index d481fd6746..a436e97b7a 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs @@ -35,7 +35,7 @@ pub trait ForwarderRaw: )); } } else { - for payment in payments.into_iter() { + for payment in payments.iter() { let _ = self.callback_payments().push(&( EgldOrEsdtTokenIdentifier::esdt(payment.token_identifier), payment.token_nonce, diff --git a/contracts/feature-tests/composability/vault/src/vault.rs b/contracts/feature-tests/composability/vault/src/vault.rs index 86ddbe31bb..37b0d65b9e 100644 --- a/contracts/feature-tests/composability/vault/src/vault.rs +++ b/contracts/feature-tests/composability/vault/src/vault.rs @@ -220,7 +220,7 @@ pub trait Vault { let mut new_tokens = ManagedVec::new(); - for payment in payments.into_iter() { + for payment in payments.iter() { // burn old tokens self.send().esdt_local_burn( &payment.token_identifier, diff --git a/contracts/modules/src/staking.rs b/contracts/modules/src/staking.rs index 7e3ce968d5..b9a76ecb01 100644 --- a/contracts/modules/src/staking.rs +++ b/contracts/modules/src/staking.rs @@ -22,7 +22,7 @@ pub trait StakingModule { user_whitelist: &ManagedVec, ) { for user in user_whitelist { - let _ = self.user_whitelist().insert(user); + let _ = self.user_whitelist().insert(user.clone()); } let nr_board_members = self.user_whitelist().len(); diff --git a/framework/base/src/types/heap/arg_buffer.rs b/framework/base/src/types/heap/arg_buffer.rs index c27be12f2c..dde5f89a06 100644 --- a/framework/base/src/types/heap/arg_buffer.rs +++ b/framework/base/src/types/heap/arg_buffer.rs @@ -91,7 +91,7 @@ where { fn from(managed_arg_buffer: &ManagedArgBuffer) -> Self { let mut result = Self::new(); - for m_arg in managed_arg_buffer.data.into_iter() { + for m_arg in &managed_arg_buffer.data { result.push_argument_bytes(m_arg.to_boxed_bytes().as_slice()); } result diff --git a/framework/base/src/types/interaction/managed_arg_buffer.rs b/framework/base/src/types/interaction/managed_arg_buffer.rs index e1b09441fc..fabe3f2c6d 100644 --- a/framework/base/src/types/interaction/managed_arg_buffer.rs +++ b/framework/base/src/types/interaction/managed_arg_buffer.rs @@ -168,7 +168,7 @@ where #[cfg(feature = "alloc")] pub fn to_raw_args_vec(&self) -> Vec> { let mut v = Vec::new(); - for item in self.data.into_iter() { + for item in &self.data { v.push(item.to_boxed_bytes().into_vec()); } v diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 1d87fb2274..e97cc2707c 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -3,7 +3,8 @@ use crate::{ codec::{ multi_types::MultiValue3, DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput, TopDecodeMultiLength, TopEncodeMulti, TopEncodeMultiOutput, - }, types::ManagedVecRef, + }, + types::ManagedVecRef, }; use crate::{ diff --git a/framework/base/src/types/managed/multi_value/multi_value_encoded.rs b/framework/base/src/types/managed/multi_value/multi_value_encoded.rs index a598ba9795..ca10b9ec6e 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_encoded.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_encoded.rs @@ -92,26 +92,11 @@ where try_cast_execute_or_else( v, MultiValueEncoded::from_raw_vec, - |v| MultiValueEncoded::from(&v), + MultiValueEncoded::from, ) } } -impl From<&ManagedVec> for MultiValueEncoded -where - M: ManagedTypeApi, - T: ManagedVecItem + TopEncode, -{ - #[inline] - fn from(v: &ManagedVec) -> Self { - let mut result = MultiValueEncoded::new(); - for item in v.into_iter() { - result.push(item); - } - result - } -} - impl MultiValueEncoded where M: ManagedTypeApi, @@ -181,7 +166,7 @@ where pub fn to_vec(&self) -> ManagedVec { let mut result = ManagedVec::new(); let serializer = ManagedSerializer::::new(); - for item in self.raw_buffers.into_iter() { + for item in &self.raw_buffers { result.push(serializer.top_decode_from_managed_buffer(&item)); } result @@ -198,7 +183,7 @@ where O: TopEncodeMultiOutput, H: EncodeErrorHandler, { - for elem in self.raw_buffers.into_iter() { + for elem in &self.raw_buffers { elem.multi_encode_or_handle_err(output, h)?; } Ok(()) diff --git a/framework/base/src/types/managed/multi_value/multi_value_encoded_counted.rs b/framework/base/src/types/managed/multi_value/multi_value_encoded_counted.rs index ce53008377..94b75f5fd2 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_encoded_counted.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_encoded_counted.rs @@ -136,7 +136,7 @@ where pub fn to_vec(&self) -> ManagedVec { let mut result = ManagedVec::new(); let serializer = ManagedSerializer::::new(); - for item in self.raw_buffers.into_iter() { + for item in &self.raw_buffers { result.push(serializer.top_decode_from_managed_buffer(&item)); } result @@ -156,7 +156,7 @@ where let raw_count = self.raw_buffers.len(); let count = raw_count / T::LEN; count.multi_encode_or_handle_err(output, h)?; - for elem in self.raw_buffers.into_iter() { + for elem in &self.raw_buffers { elem.multi_encode_or_handle_err(output, h)?; } Ok(()) diff --git a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs index feb99b561d..e342d88cf1 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs @@ -1,3 +1,5 @@ +use core::borrow::Borrow; + use multiversx_sc_codec::multi_types::MultiValueVec; use crate::{ @@ -181,8 +183,8 @@ where O: TopEncodeMultiOutput, H: EncodeErrorHandler, { - for elem in self.0.into_iter() { - elem.multi_encode_or_handle_err(output, h)?; + for elem in &self.0 { + elem.borrow().multi_encode_or_handle_err(output, h)?; } Ok(()) } diff --git a/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs b/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs index 0cb695e0d5..4f51989a9b 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs @@ -1,3 +1,5 @@ +use core::borrow::Borrow; + use crate::{ abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::ManagedTypeApi, @@ -122,8 +124,8 @@ where H: EncodeErrorHandler, { self.len().multi_encode_or_handle_err(output, h)?; - for elem in self.contents.into_iter() { - elem.multi_encode_or_handle_err(output, h)?; + for elem in &self.contents { + elem.borrow().multi_encode_or_handle_err(output, h)?; } Ok(()) } diff --git a/framework/base/src/types/managed/wrapped/managed_ref.rs b/framework/base/src/types/managed/wrapped/managed_ref.rs index f618063b3c..ba99ab0880 100644 --- a/framework/base/src/types/managed/wrapped/managed_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_ref.rs @@ -60,13 +60,13 @@ where } } -impl<'a, M, T> Clone for ManagedRef<'a, M, T> +impl<'a, M, T> ManagedRef<'a, M, T> where M: ManagedTypeApi, T: ManagedType, { - #[inline] - fn clone(&self) -> Self { + /// Clones the reference itself, not the object contained therein. + pub fn clone_ref(&self) -> Self { Self { _phantom_m: PhantomData, _phantom_t: PhantomData, diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index ab93734a06..ebb0f0d157 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -521,7 +521,7 @@ where fn clone(&self) -> Self { let mut result = ManagedVec::new(); for item in self.into_iter() { - result.push(item.clone()) + result.push(item.borrow().clone()) } result } @@ -611,7 +611,8 @@ where } else { let mut nested_buffer = output.start_nested_encode(); for item in self { - item.dep_encode_or_handle_err(&mut nested_buffer, h)?; + item.borrow() + .dep_encode_or_handle_err(&mut nested_buffer, h)?; } output.finalize_nested_encode(nested_buffer); Ok(()) @@ -631,7 +632,7 @@ where { self.len().dep_encode_or_handle_err(dest, h)?; for item in self { - item.dep_encode_or_handle_err(dest, h)?; + item.borrow().dep_encode_or_handle_err(dest, h)?; } Ok(()) } @@ -748,7 +749,7 @@ where fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let mut dbg_list = f.debug_list(); for item in self.into_iter() { - dbg_list.entry(&item); + dbg_list.entry(item.borrow()); } dbg_list.finish() } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs index 8e0da8727c..b688bb466c 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs @@ -2,34 +2,34 @@ use crate::api::ManagedTypeApi; use super::{ManagedVec, ManagedVecItem, ManagedVecItemPayload}; -impl<'a, M, T> IntoIterator for &'a ManagedVec +impl IntoIterator for ManagedVec where M: ManagedTypeApi, T: ManagedVecItem, { type Item = T; - type IntoIter = ManagedVecOwnedIterator<'a, M, T>; + type IntoIter = ManagedVecOwnedIterator; fn into_iter(self) -> Self::IntoIter { ManagedVecOwnedIterator::new(self) } } -pub struct ManagedVecOwnedIterator<'a, M, T> +pub struct ManagedVecOwnedIterator where M: ManagedTypeApi, T: ManagedVecItem, { - managed_vec: &'a ManagedVec, + managed_vec: ManagedVec, byte_start: usize, byte_end: usize, } -impl<'a, M, T> ManagedVecOwnedIterator<'a, M, T> +impl ManagedVecOwnedIterator where M: ManagedTypeApi, T: ManagedVecItem, { - pub(crate) fn new(managed_vec: &'a ManagedVec) -> Self { + pub(crate) fn new(managed_vec: ManagedVec) -> Self { let byte_end = managed_vec.byte_len(); ManagedVecOwnedIterator { managed_vec, @@ -39,7 +39,7 @@ where } } -impl<'a, M, T> Iterator for ManagedVecOwnedIterator<'a, M, T> +impl Iterator for ManagedVecOwnedIterator where M: ManagedTypeApi, T: ManagedVecItem, @@ -70,14 +70,14 @@ where } } -impl<'a, M, T> ExactSizeIterator for ManagedVecOwnedIterator<'a, M, T> +impl ExactSizeIterator for ManagedVecOwnedIterator where M: ManagedTypeApi, T: ManagedVecItem, { } -impl<'a, M, T> DoubleEndedIterator for ManagedVecOwnedIterator<'a, M, T> +impl DoubleEndedIterator for ManagedVecOwnedIterator where M: ManagedTypeApi, T: ManagedVecItem, @@ -98,15 +98,15 @@ where } } -impl<'a, M, T> Clone for ManagedVecOwnedIterator<'a, M, T> +impl Clone for ManagedVecOwnedIterator where M: ManagedTypeApi, - T: ManagedVecItem, + T: ManagedVecItem + Clone, { fn clone(&self) -> Self { let byte_end = self.byte_end; Self { - managed_vec: self.managed_vec, + managed_vec: self.managed_vec.clone(), byte_start: self.byte_start, byte_end, } 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 987cb60614..de78fd5e6f 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref.rs @@ -13,6 +13,11 @@ impl ManagedVecRef<'_, T> where T: ManagedVecItem, { + /// Creates a new ManagedVecRef instance. + /// + /// ## Safety + /// + /// The ManagedVecRef object might not drop its content, effectively leading to a leak. pub unsafe fn new(item: T) -> Self { ManagedVecRef { _phantom: PhantomData, diff --git a/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs index 4703a1f61b..9720ba741f 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs @@ -2,6 +2,18 @@ use crate::api::ManagedTypeApi; use super::{ManagedVec, ManagedVecItem, ManagedVecItemPayload}; +impl<'a, M, T> IntoIterator for &'a ManagedVec +where + M: ManagedTypeApi, + T: ManagedVecItem, +{ + type Item = T::Ref<'a>; + type IntoIter = ManagedVecRefIterator<'a, M, T>; + fn into_iter(self) -> Self::IntoIter { + ManagedVecRefIterator::new(self) + } +} + pub struct ManagedVecRefIterator<'a, M, T> where M: ManagedTypeApi, diff --git a/framework/base/src/types/managed/wrapped/traits/mergeable.rs b/framework/base/src/types/managed/wrapped/traits/mergeable.rs index 51298ba130..295357f9b6 100644 --- a/framework/base/src/types/managed/wrapped/traits/mergeable.rs +++ b/framework/base/src/types/managed/wrapped/traits/mergeable.rs @@ -21,7 +21,7 @@ pub trait Mergeable { where Self: Sized + ManagedVecItem, { - for item in &others { + for item in others { self.merge_with(item); } } diff --git a/framework/scenario/tests/managed_ref_test.rs b/framework/scenario/tests/managed_ref_test.rs index 2edfeac515..dedba7904f 100644 --- a/framework/scenario/tests/managed_ref_test.rs +++ b/framework/scenario/tests/managed_ref_test.rs @@ -16,9 +16,9 @@ where let obj_ref = obj.as_ref(); assert_eq!( obj_ref.get_handle(), - ManagedRef::get_raw_handle_of_ref(obj_ref.clone()) + ManagedRef::get_raw_handle_of_ref(obj_ref.clone_ref()) ); - let obj_clone: T = Clone::clone(&obj_ref); + let obj_clone: T = obj_ref.clone(); assert_eq!(obj, obj_clone); assert_ne!(obj_ref.get_handle(), obj_clone.get_handle()); } From 490a31c3adf3524b64a8229361d48dbedcc7d157 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 29 Nov 2024 17:16:08 +0200 Subject: [PATCH 049/133] stack overflow fix --- .../base/src/types/managed/multi_value/multi_value_encoded.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/multi_value_encoded.rs b/framework/base/src/types/managed/multi_value/multi_value_encoded.rs index ca10b9ec6e..e69d741f4a 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_encoded.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_encoded.rs @@ -87,12 +87,11 @@ where T: ManagedVecItem + TopEncode + 'static, { #[inline] - #[rustfmt::skip] fn from(v: ManagedVec) -> Self { try_cast_execute_or_else( v, MultiValueEncoded::from_raw_vec, - MultiValueEncoded::from, + MultiValueEncoded::from_iter, ) } } From 809b71a17ee9af5760f1d3ad83bfe6244e7a0f41 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 29 Nov 2024 17:49:15 +0200 Subject: [PATCH 050/133] ManagedVecItem - ref for tuples --- .../basic-features/src/echo_managed.rs | 4 ++-- .../multi_value/multi_value_managed_vec.rs | 16 +++++++++++++++- .../types/managed/wrapped/managed_vec_item.rs | 10 ++++------ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/contracts/feature-tests/basic-features/src/echo_managed.rs b/contracts/feature-tests/basic-features/src/echo_managed.rs index ffabfa5b16..98154b2d9f 100644 --- a/contracts/feature-tests/basic-features/src/echo_managed.rs +++ b/contracts/feature-tests/basic-features/src/echo_managed.rs @@ -159,11 +159,11 @@ pub trait EchoManagedTypes { MultiValue3>>, > { let mut result = MultiValueEncoded::new(); - for triple in address_number_pairs.into_iter() { + for triple in address_number_pairs { let (address, x, counted_list) = triple.into_tuple(); let mut counted_lazy = MultiValueEncodedCounted::new(); let v = counted_list.into_vec(); - for pair in &v { + for pair in v { counted_lazy.push(pair); } result.push((address, x, counted_lazy).into()); diff --git a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs index e342d88cf1..aa34600120 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs @@ -9,7 +9,7 @@ use crate::{ DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput, TopEncodeMulti, TopEncodeMultiOutput, Vec, }, - types::ManagedType, + types::{ManagedType, ManagedVecOwnedIterator}, }; use crate::types::{ManagedVec, ManagedVecItem, ManagedVecRefIterator}; @@ -144,6 +144,20 @@ where } } +impl IntoIterator for MultiValueManagedVec +where + M: ManagedTypeApi, + T: ManagedVecItem, +{ + type Item = T; + + type IntoIter = ManagedVecOwnedIterator; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + impl<'a, M, T> IntoIterator for &'a MultiValueManagedVec where M: ManagedTypeApi, diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index d14ae0067f..62e62ad4dd 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -324,7 +324,7 @@ where { type PAYLOAD = <(T1, (T2, ())) as ManagedVecItemNestedTuple>::PAYLOAD; const SKIPS_RESERIALIZATION: bool = T1::SKIPS_RESERIALIZATION && T2::SKIPS_RESERIALIZATION; - type Ref<'a> = Self; + type Ref<'a> = ManagedVecRef<'a, Self>; fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; @@ -338,8 +338,7 @@ where } unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { - // TODO: tuple of refs - Self::read_from_payload(payload) + ManagedVecRef::new(Self::read_from_payload(payload)) } fn save_to_payload(self, payload: &mut Self::PAYLOAD) { @@ -362,7 +361,7 @@ where { type PAYLOAD = <(T1, (T2, (T3, ()))) as ManagedVecItemNestedTuple>::PAYLOAD; const SKIPS_RESERIALIZATION: bool = T1::SKIPS_RESERIALIZATION && T2::SKIPS_RESERIALIZATION; - type Ref<'a> = Self; + type Ref<'a> = ManagedVecRef<'a, Self>; fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; @@ -377,8 +376,7 @@ where } unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { - // TODO: tuple of refs - Self::read_from_payload(payload) + ManagedVecRef::new(Self::read_from_payload(payload)) } fn save_to_payload(self, payload: &mut Self::PAYLOAD) { From 04997020dbeaa242a08de28bba5bbfb7983cd0cd Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Fri, 29 Nov 2024 21:30:27 +0100 Subject: [PATCH 051/133] initial implementation dynamic esdts --- chain/core/src/builtin_func_names.rs | 6 + chain/core/src/types/flags/esdt_local_role.rs | 47 +++++- .../src/types/flags/esdt_local_role_flags.rs | 5 + chain/core/src/types/flags/esdt_token_type.rs | 30 +++- .../contract_base/wrappers/send_wrapper.rs | 82 +++++++++++ .../system_proxy/builtin_func_proxy.rs | 138 +++++++++++++++++- .../system_proxy/esdt_system_sc_proxy.rs | 26 +++- .../system_proxy/legacy_system_sc_proxy.rs | 38 +++-- 8 files changed, 355 insertions(+), 17 deletions(-) diff --git a/chain/core/src/builtin_func_names.rs b/chain/core/src/builtin_func_names.rs index 108ed29016..51777f201b 100644 --- a/chain/core/src/builtin_func_names.rs +++ b/chain/core/src/builtin_func_names.rs @@ -14,3 +14,9 @@ pub const SET_USERNAME_FUNC_NAME: &str = "SetUserName"; pub const MIGRATE_USERNAME_FUNC_NAME: &str = "migrateUserName"; pub const DELETE_USERNAME_FUNC_NAME: &str = "DeleteUserName"; pub const UPGRADE_CONTRACT_FUNC_NAME: &str = "upgradeContract"; +pub const ESDT_SET_TOKEN_TYPE_FUNC_NAME: &str = "ESDTSetTokenType"; +pub const ESDT_MODIFY_ROYALTIES_FUNC_NAME: &str = "ESDTModifyRoyalties"; +pub const ESDT_SET_NEW_URIS_FUNC_NAME: &str = "ESDTSetNewURIs"; +pub const ESDT_MODIFY_CREATOR_FUNC_NAME: &str = "ESDTModifyCreator"; +pub const ESDT_METADATA_RECREATE_FUNC_NAME: &str = "ESDTMetaDataRecreate"; +pub const ESDT_METADATA_UPDATE_FUNC_NAME: &str = "ESDTMetaDataUpdate"; diff --git a/chain/core/src/types/flags/esdt_local_role.rs b/chain/core/src/types/flags/esdt_local_role.rs index 048d3876ce..3634e5d891 100644 --- a/chain/core/src/types/flags/esdt_local_role.rs +++ b/chain/core/src/types/flags/esdt_local_role.rs @@ -13,6 +13,11 @@ const ESDT_ROLE_NFT_BURN: &str = "ESDTRoleNFTBurn"; const ESDT_ROLE_NFT_ADD_URI: &str = "ESDTRoleNFTAddURI"; const ESDT_ROLE_NFT_UPDATE_ATTRIBUTES: &str = "ESDTRoleNFTUpdateAttributes"; const ESDT_ROLE_TRANSFER: &str = "ESDTTransferRole"; +const ESDT_ROLE_SET_NEW_URI: &str = "ESDTRoleSetNewURI"; +const ESDT_ROLE_MODIFY_ROYALTIES: &str = "ESDTRoleModifyRoyalties"; +const ESDT_ROLE_MODIFY_CREATOR: &str = "ESDTRoleModifyCreator"; +const ESDT_ROLE_NFT_RECREATE: &str = "ESDTRoleNFTRecreate"; +const ESDT_ROLE_NFT_UPDATE: &str = "ESDTRoleNFTUpdate"; #[derive(TopDecode, TopEncode, NestedDecode, NestedEncode, Clone, PartialEq, Eq, Debug, Copy)] pub enum EsdtLocalRole { @@ -25,6 +30,11 @@ pub enum EsdtLocalRole { NftAddUri, NftUpdateAttributes, Transfer, + SetNewUri, + ModifyRoyalties, + ModifyCreator, + NftRecreate, + NftUpdate, } impl EsdtLocalRole { @@ -39,6 +49,11 @@ impl EsdtLocalRole { Self::NftAddUri => 6, Self::NftUpdateAttributes => 7, Self::Transfer => 8, + Self::SetNewUri => 9, + Self::ModifyRoyalties => 10, + Self::ModifyCreator => 11, + Self::NftRecreate => 12, + Self::NftUpdate => 13, } } @@ -57,6 +72,11 @@ impl EsdtLocalRole { Self::NftAddUri => ESDT_ROLE_NFT_ADD_URI, Self::NftUpdateAttributes => ESDT_ROLE_NFT_UPDATE_ATTRIBUTES, Self::Transfer => ESDT_ROLE_TRANSFER, + Self::SetNewUri => ESDT_ROLE_SET_NEW_URI, + Self::ModifyRoyalties => ESDT_ROLE_MODIFY_ROYALTIES, + Self::ModifyCreator => ESDT_ROLE_MODIFY_CREATOR, + Self::NftRecreate => ESDT_ROLE_NFT_RECREATE, + Self::NftUpdate => ESDT_ROLE_NFT_UPDATE, } } @@ -71,13 +91,18 @@ impl EsdtLocalRole { Self::NftAddUri => EsdtLocalRoleFlags::NFT_ADD_URI, Self::NftUpdateAttributes => EsdtLocalRoleFlags::NFT_UPDATE_ATTRIBUTES, Self::Transfer => EsdtLocalRoleFlags::TRANSFER, + Self::SetNewUri => EsdtLocalRoleFlags::SET_NEW_URI, + Self::ModifyRoyalties => EsdtLocalRoleFlags::MODIFY_ROYALTIES, + Self::ModifyCreator => EsdtLocalRoleFlags::MODIFY_CREATOR, + Self::NftRecreate => EsdtLocalRoleFlags::NFT_RECREATE, + Self::NftUpdate => EsdtLocalRoleFlags::NFT_UPDATE, } } } // TODO: can be done with macros, but I didn't find a public library that does it and is no_std // we can implement it, it's easy -const ALL_ROLES: [EsdtLocalRole; 8] = [ +const ALL_ROLES: [EsdtLocalRole; 13] = [ EsdtLocalRole::Mint, EsdtLocalRole::Burn, EsdtLocalRole::NftCreate, @@ -86,6 +111,11 @@ const ALL_ROLES: [EsdtLocalRole; 8] = [ EsdtLocalRole::NftAddUri, EsdtLocalRole::NftUpdateAttributes, EsdtLocalRole::Transfer, + EsdtLocalRole::SetNewUri, + EsdtLocalRole::ModifyRoyalties, + EsdtLocalRole::ModifyCreator, + EsdtLocalRole::NftRecreate, + EsdtLocalRole::NftUpdate, ]; impl EsdtLocalRole { @@ -106,6 +136,11 @@ impl From for EsdtLocalRole { 6 => Self::NftAddUri, 7 => Self::NftUpdateAttributes, 8 => Self::Transfer, + 9 => Self::SetNewUri, + 10 => Self::ModifyRoyalties, + 11 => Self::ModifyCreator, + 12 => Self::NftRecreate, + 13 => Self::NftUpdate, _ => Self::None, } } @@ -130,6 +165,16 @@ impl<'a> From<&'a [u8]> for EsdtLocalRole { Self::NftUpdateAttributes } else if byte_slice == ESDT_ROLE_TRANSFER.as_bytes() { Self::Transfer + } else if byte_slice == ESDT_ROLE_SET_NEW_URI.as_bytes() { + Self::SetNewUri + } else if byte_slice == ESDT_ROLE_MODIFY_ROYALTIES.as_bytes() { + Self::ModifyRoyalties + } else if byte_slice == ESDT_ROLE_MODIFY_CREATOR.as_bytes() { + Self::ModifyCreator + } else if byte_slice == ESDT_ROLE_NFT_RECREATE.as_bytes() { + Self::NftRecreate + } else if byte_slice == ESDT_ROLE_NFT_UPDATE.as_bytes() { + Self::NftUpdate } else { Self::None } diff --git a/chain/core/src/types/flags/esdt_local_role_flags.rs b/chain/core/src/types/flags/esdt_local_role_flags.rs index 29be64aba2..cac9aa6795 100644 --- a/chain/core/src/types/flags/esdt_local_role_flags.rs +++ b/chain/core/src/types/flags/esdt_local_role_flags.rs @@ -15,6 +15,11 @@ bitflags! { const NFT_ADD_URI = 0b00100000; const NFT_UPDATE_ATTRIBUTES = 0b01000000; const TRANSFER = 0b10000000; + const SET_NEW_URI = 0b00000001_00000000; + const MODIFY_ROYALTIES = 0b00000010_00000000; + const MODIFY_CREATOR = 0b00000100_00000000; + const NFT_RECREATE = 0b00001000_00000000; + const NFT_UPDATE = 0b00010000_00000000; } } diff --git a/chain/core/src/types/flags/esdt_token_type.rs b/chain/core/src/types/flags/esdt_token_type.rs index 74db07c9a6..bfa2b07192 100644 --- a/chain/core/src/types/flags/esdt_token_type.rs +++ b/chain/core/src/types/flags/esdt_token_type.rs @@ -9,6 +9,10 @@ const ESDT_TYPE_FUNGIBLE: &[u8] = b"FungibleESDT"; const ESDT_TYPE_NON_FUNGIBLE: &[u8] = b"NonFungibleESDT"; const ESDT_TYPE_SEMI_FUNGIBLE: &[u8] = b"SemiFungibleESDT"; const ESDT_TYPE_META: &[u8] = b"MetaESDT"; +const ESDT_TYPE_NON_FUNGIBLE_V2: &[u8] = b"NonFungibleESDTv2"; +const ESDT_TYPE_DYNAMIC_NON_FUNGIBLE: &[u8] = b"DynamicNonFungibleESDT"; +const ESDT_TYPE_DYNAMIC_SEMI_FUNGIBLE: &[u8] = b"DynamicSemiFungibleESDT"; +const ESDT_TYPE_DYNAMIC_META: &[u8] = b"DynamicMetaESDT"; const ESDT_TYPE_INVALID: &[u8] = &[]; // Note: In the current implementation, SemiFungible is never returned @@ -19,6 +23,10 @@ pub enum EsdtTokenType { NonFungible, SemiFungible, Meta, + NonFungibleV2, + DynamicNFT, + DynamicSFT, + DynamicMeta, Invalid, } @@ -37,7 +45,11 @@ impl EsdtTokenType { Self::NonFungible => 1, Self::SemiFungible => 2, Self::Meta => 3, - Self::Invalid => 4, + Self::NonFungibleV2 => 4, + Self::DynamicNFT => 5, + Self::DynamicSFT => 6, + Self::DynamicMeta => 7, + Self::Invalid => 8, } } @@ -47,6 +59,10 @@ impl EsdtTokenType { Self::NonFungible => ESDT_TYPE_NON_FUNGIBLE, Self::SemiFungible => ESDT_TYPE_SEMI_FUNGIBLE, Self::Meta => ESDT_TYPE_META, + Self::NonFungibleV2 => ESDT_TYPE_NON_FUNGIBLE_V2, + Self::DynamicNFT => ESDT_TYPE_DYNAMIC_NON_FUNGIBLE, + Self::DynamicSFT => ESDT_TYPE_DYNAMIC_SEMI_FUNGIBLE, + Self::DynamicMeta => ESDT_TYPE_DYNAMIC_META, Self::Invalid => ESDT_TYPE_INVALID, } } @@ -60,6 +76,10 @@ impl From for EsdtTokenType { 1 => Self::NonFungible, 2 => Self::SemiFungible, 3 => Self::Meta, + 4 => Self::NonFungibleV2, + 5 => Self::DynamicNFT, + 6 => Self::DynamicSFT, + 7 => Self::DynamicMeta, _ => Self::Invalid, } } @@ -76,6 +96,14 @@ impl<'a> From<&'a [u8]> for EsdtTokenType { Self::SemiFungible } else if byte_slice == ESDT_TYPE_META { Self::Meta + } else if byte_slice == ESDT_TYPE_NON_FUNGIBLE_V2 { + Self::NonFungibleV2 + } else if byte_slice == ESDT_TYPE_DYNAMIC_NON_FUNGIBLE { + Self::DynamicNFT + } else if byte_slice == ESDT_TYPE_DYNAMIC_SEMI_FUNGIBLE { + Self::DynamicSFT + } else if byte_slice == ESDT_TYPE_DYNAMIC_META { + Self::DynamicMeta } else { Self::Invalid } diff --git a/framework/base/src/contract_base/wrappers/send_wrapper.rs b/framework/base/src/contract_base/wrappers/send_wrapper.rs index 0c23b67cd4..468d75c92c 100644 --- a/framework/base/src/contract_base/wrappers/send_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/send_wrapper.rs @@ -1,5 +1,7 @@ use core::marker::PhantomData; +use multiversx_chain_core::types::EsdtTokenType; + use crate::codec::Empty; use crate::types::ManagedRef; @@ -763,4 +765,84 @@ where .nft_update_attributes(token_id, nft_nonce, new_attributes) .sync_call() } + + /// Sets the token type for a specific token. + pub fn esdt_set_token_type(&self, token_id: &TokenIdentifier, token_type: EsdtTokenType) { + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(GasLeft) + .typed(system_proxy::UserBuiltinProxy) + .esdt_set_token_type(token_id, token_type) + .sync_call() + } + + /// Modifies royalties for a specific token. + pub fn esdt_modify_royalties( + &self, + token_id: &TokenIdentifier, + nonce: u64, + new_royalty: u64, + ) { + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(GasLeft) + .typed(system_proxy::UserBuiltinProxy) + .esdt_modify_royalties(token_id, nonce, new_royalty) + .sync_call() + } + + /// Sets new uris for a specific token. + pub fn esdt_nft_set_new_uris( + &self, + token_id: &TokenIdentifier, + nonce: u64, + uris: &ManagedVec>, + ) { + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(GasLeft) + .typed(system_proxy::UserBuiltinProxy) + .esdt_nft_set_new_uris(token_id, nonce, uris) + .sync_call() + } + + /// Changes the creator of a specific token into the caller. + pub fn esdt_nft_modify_creator(&self, token_id: &TokenIdentifier, nonce: u64) { + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(GasLeft) + .typed(system_proxy::UserBuiltinProxy) + .esdt_nft_modify_creator(token_id, nonce) + .sync_call() + } + + /// Recreates an ESDT token with the newly specified attributes. + pub fn esdt_metadata_recreate( + &self, + token_id: TokenIdentifier, + nonce: u64, + new_attributes: &T, + ) { + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(GasLeft) + .typed(system_proxy::UserBuiltinProxy) + .esdt_metadata_recreate(token_id, nonce, new_attributes) + .sync_call() + } + + /// Updates an ESDT token with the newly specified attributes. + pub fn esdt_metadata_update( + &self, + token_id: &TokenIdentifier, + nonce: u64, + new_attributes: &T, + ) { + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(GasLeft) + .typed(system_proxy::UserBuiltinProxy) + .esdt_metadata_update(token_id, nonce, new_attributes) + .sync_call() + } } diff --git a/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs b/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs index 1bf7c3a1fc..1612965f4b 100644 --- a/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs @@ -1,15 +1,17 @@ use multiversx_sc_codec::{Empty, TopEncode}; use crate::types::{ - BigUint, ManagedAddress, ManagedBuffer, ManagedVec, NotPayable, ProxyArg, TokenIdentifier, Tx, - TxEnv, TxFrom, TxGas, TxProxyTrait, TxTo, TxTypedCall, + BigUint, EsdtTokenType, ManagedAddress, ManagedBuffer, ManagedVec, NotPayable, ProxyArg, + TokenIdentifier, Tx, TxEnv, TxFrom, TxGas, TxProxyTrait, TxTo, TxTypedCall, }; use crate::chain_core::builtin_func_names::{ CHANGE_OWNER_BUILTIN_FUNC_NAME, CLAIM_DEVELOPER_REWARDS_FUNC_NAME, DELETE_USERNAME_FUNC_NAME, - ESDT_LOCAL_BURN_FUNC_NAME, ESDT_LOCAL_MINT_FUNC_NAME, ESDT_NFT_ADD_QUANTITY_FUNC_NAME, - ESDT_NFT_ADD_URI_FUNC_NAME, ESDT_NFT_BURN_FUNC_NAME, ESDT_NFT_CREATE_FUNC_NAME, - ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME, SET_USERNAME_FUNC_NAME, + ESDT_LOCAL_BURN_FUNC_NAME, ESDT_LOCAL_MINT_FUNC_NAME, ESDT_METADATA_RECREATE_FUNC_NAME, + ESDT_METADATA_UPDATE_FUNC_NAME, ESDT_MODIFY_CREATOR_FUNC_NAME, ESDT_MODIFY_ROYALTIES_FUNC_NAME, + ESDT_NFT_ADD_QUANTITY_FUNC_NAME, ESDT_NFT_ADD_URI_FUNC_NAME, ESDT_NFT_BURN_FUNC_NAME, + ESDT_NFT_CREATE_FUNC_NAME, ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME, ESDT_SET_NEW_URIS_FUNC_NAME, + ESDT_SET_TOKEN_TYPE_FUNC_NAME, SET_USERNAME_FUNC_NAME, }; /// Proxy describing the user builtin function signatures. @@ -214,4 +216,130 @@ where tx.original_result() } + + pub fn esdt_set_token_type< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + token_id: Arg0, + token_type: Arg1, + ) -> TxTypedCall { + let tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_SET_TOKEN_TYPE_FUNC_NAME) + .argument(&token_id) + .argument(&token_type); + + tx.original_result() + } + + pub fn esdt_modify_royalties< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg, + >( + self, + token_id: Arg0, + nonce: Arg1, + new_royalty: Arg2, + ) -> TxTypedCall { + let tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_MODIFY_ROYALTIES_FUNC_NAME) + .argument(&token_id) + .argument(&nonce) + .argument(&new_royalty); + + tx.original_result() + } + + pub fn esdt_nft_set_new_uris>, Arg1: ProxyArg>( + self, + token_id: Arg0, + nonce: Arg1, + uris: &ManagedVec>, + ) -> TxTypedCall { + let mut tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_SET_NEW_URIS_FUNC_NAME) + .argument(&token_id) + .argument(&nonce); + + if uris.is_empty() { + // at least one URI is required, so we push an empty one + tx = tx.argument(&Empty); + } else { + // The API function has the last argument as variadic, + // so we top-encode each and send as separate argument + for uri in uris { + tx = tx.argument(&uri); + } + } + + tx.original_result() + } + + pub fn esdt_nft_modify_creator< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + token_id: Arg0, + nonce: Arg1, + ) -> TxTypedCall { + let tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_MODIFY_CREATOR_FUNC_NAME) + .argument(&token_id) + .argument(&nonce); + + tx.original_result() + } + + pub fn esdt_metadata_recreate< + T: TopEncode, + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + token_id: Arg0, + nonce: Arg1, + new_attributes: &T, + ) -> TxTypedCall { + let tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_METADATA_RECREATE_FUNC_NAME) + .argument(&token_id) + .argument(&nonce) + .argument(&new_attributes); + + tx.original_result() + } + + pub fn esdt_metadata_update< + T: TopEncode, + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + token_id: Arg0, + nonce: Arg1, + new_attributes: &T, + ) -> TxTypedCall { + let tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_METADATA_UPDATE_FUNC_NAME) + .argument(&token_id) + .argument(&nonce) + .argument(&new_attributes); + + tx.original_result() + } } diff --git a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs index 979f9d1d60..a68950b0f9 100644 --- a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs @@ -14,6 +14,8 @@ const ISSUE_NON_FUNGIBLE_ENDPOINT_NAME: &str = "issueNonFungible"; const ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME: &str = "issueSemiFungible"; const REGISTER_META_ESDT_ENDPOINT_NAME: &str = "registerMetaESDT"; const ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME: &str = "registerAndSetAllRoles"; +const REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME: &str = "registerDynamic"; +const REGISTER_AND_SET_ALL_ROLES_DYNAMIC_ESDT_ENDPOINT_NAME: &str = "registerAndSetAllRolesDynamic"; /// The specific `Tx` type produces by the issue operations of the ESDTSystemSCProxy. pub type IssueCall = Tx< @@ -214,11 +216,29 @@ where EsdtTokenType::NonFungible => "NFT", EsdtTokenType::SemiFungible => "SFT", EsdtTokenType::Meta => "META", + EsdtTokenType::NonFungibleV2 => "NFT", + EsdtTokenType::DynamicNFT => "NFT", + EsdtTokenType::DynamicSFT => "SFT", + EsdtTokenType::DynamicMeta => "META", + EsdtTokenType::Invalid => "", + }; + + let endpoint = match token_type { + EsdtTokenType::Fungible + | EsdtTokenType::NonFungible + | EsdtTokenType::SemiFungible + | EsdtTokenType::Meta => ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME, + + EsdtTokenType::NonFungibleV2 + | EsdtTokenType::DynamicNFT + | EsdtTokenType::DynamicSFT + | EsdtTokenType::DynamicMeta => REGISTER_AND_SET_ALL_ROLES_DYNAMIC_ESDT_ENDPOINT_NAME, + EsdtTokenType::Invalid => "", }; self.wrapped_tx - .raw_call(ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME) + .raw_call(endpoint) .egld(issue_cost) .argument(&token_display_name) .argument(&token_ticker) @@ -246,6 +266,10 @@ where EsdtTokenType::NonFungible => ISSUE_NON_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::SemiFungible => ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::Meta => REGISTER_META_ESDT_ENDPOINT_NAME, + EsdtTokenType::NonFungibleV2 + | EsdtTokenType::DynamicNFT + | EsdtTokenType::DynamicSFT + | EsdtTokenType::DynamicMeta => REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME, EsdtTokenType::Invalid => "", }; diff --git a/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs index 6f74b80812..4af1f5b9b2 100644 --- a/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs @@ -17,6 +17,8 @@ const ISSUE_NON_FUNGIBLE_ENDPOINT_NAME: &str = "issueNonFungible"; const ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME: &str = "issueSemiFungible"; const REGISTER_META_ESDT_ENDPOINT_NAME: &str = "registerMetaESDT"; const ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME: &str = "registerAndSetAllRoles"; +const REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME: &str = "registerDynamic"; +const REGISTER_AND_SET_ALL_ROLES_DYNAMIC_ESDT_ENDPOINT_NAME: &str = "registerAndSetAllRolesDynamic"; /// Proxy for the ESDT system smart contract. /// Unlike other contract proxies, this one has a fixed address, @@ -188,18 +190,32 @@ where EsdtTokenType::NonFungible => "NFT", EsdtTokenType::SemiFungible => "SFT", EsdtTokenType::Meta => "META", + EsdtTokenType::NonFungibleV2 => "NFT", + EsdtTokenType::DynamicNFT => "NFT", + EsdtTokenType::DynamicSFT => "SFT", + EsdtTokenType::DynamicMeta => "META", EsdtTokenType::Invalid => "", }; - ContractCallWithEgld::new( - esdt_system_sc_address, - ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME, - issue_cost, - ) - .argument(&token_display_name) - .argument(&token_ticker) - .argument(&token_type_name) - .argument(&num_decimals) + let endpoint = match token_type { + EsdtTokenType::Fungible + | EsdtTokenType::NonFungible + | EsdtTokenType::SemiFungible + | EsdtTokenType::Meta => ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME, + + EsdtTokenType::NonFungibleV2 + | EsdtTokenType::DynamicNFT + | EsdtTokenType::DynamicSFT + | EsdtTokenType::DynamicMeta => REGISTER_AND_SET_ALL_ROLES_DYNAMIC_ESDT_ENDPOINT_NAME, + + EsdtTokenType::Invalid => "", + }; + + ContractCallWithEgld::new(esdt_system_sc_address, endpoint, issue_cost) + .argument(&token_display_name) + .argument(&token_ticker) + .argument(&token_type_name) + .argument(&num_decimals) } /// Deduplicates code from all the possible issue functions @@ -219,6 +235,10 @@ where EsdtTokenType::NonFungible => ISSUE_NON_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::SemiFungible => ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::Meta => REGISTER_META_ESDT_ENDPOINT_NAME, + EsdtTokenType::NonFungibleV2 + | EsdtTokenType::DynamicNFT + | EsdtTokenType::DynamicSFT + | EsdtTokenType::DynamicMeta => REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME, EsdtTokenType::Invalid => "", }; From d03613b21781ac909ea21b4340baea6c8c40a720 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Fri, 29 Nov 2024 21:41:50 +0100 Subject: [PATCH 052/133] nftv2 moved to old endpoint --- .../system_proxy/esdt_system_sc_proxy.rs | 31 +++++++++---------- .../system_proxy/legacy_system_sc_proxy.rs | 31 +++++++++---------- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs index a68950b0f9..87e4e1fd7b 100644 --- a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs @@ -213,26 +213,24 @@ where ) -> IssueCall { let token_type_name = match token_type { EsdtTokenType::Fungible => "FNG", - EsdtTokenType::NonFungible => "NFT", - EsdtTokenType::SemiFungible => "SFT", - EsdtTokenType::Meta => "META", - EsdtTokenType::NonFungibleV2 => "NFT", - EsdtTokenType::DynamicNFT => "NFT", - EsdtTokenType::DynamicSFT => "SFT", - EsdtTokenType::DynamicMeta => "META", + EsdtTokenType::NonFungible + | EsdtTokenType::NonFungibleV2 + | EsdtTokenType::DynamicNFT => "NFT", + EsdtTokenType::SemiFungible | EsdtTokenType::DynamicSFT => "SFT", + EsdtTokenType::Meta | EsdtTokenType::DynamicMeta => "META", EsdtTokenType::Invalid => "", }; let endpoint = match token_type { EsdtTokenType::Fungible | EsdtTokenType::NonFungible + | EsdtTokenType::NonFungibleV2 | EsdtTokenType::SemiFungible | EsdtTokenType::Meta => ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME, - EsdtTokenType::NonFungibleV2 - | EsdtTokenType::DynamicNFT - | EsdtTokenType::DynamicSFT - | EsdtTokenType::DynamicMeta => REGISTER_AND_SET_ALL_ROLES_DYNAMIC_ESDT_ENDPOINT_NAME, + EsdtTokenType::DynamicNFT | EsdtTokenType::DynamicSFT | EsdtTokenType::DynamicMeta => { + REGISTER_AND_SET_ALL_ROLES_DYNAMIC_ESDT_ENDPOINT_NAME + }, EsdtTokenType::Invalid => "", }; @@ -263,13 +261,14 @@ where ) -> IssueCall { let endpoint_name = match token_type { EsdtTokenType::Fungible => ISSUE_FUNGIBLE_ENDPOINT_NAME, - EsdtTokenType::NonFungible => ISSUE_NON_FUNGIBLE_ENDPOINT_NAME, + EsdtTokenType::NonFungible | EsdtTokenType::NonFungibleV2 => { + ISSUE_NON_FUNGIBLE_ENDPOINT_NAME + }, EsdtTokenType::SemiFungible => ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::Meta => REGISTER_META_ESDT_ENDPOINT_NAME, - EsdtTokenType::NonFungibleV2 - | EsdtTokenType::DynamicNFT - | EsdtTokenType::DynamicSFT - | EsdtTokenType::DynamicMeta => REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME, + EsdtTokenType::DynamicNFT | EsdtTokenType::DynamicSFT | EsdtTokenType::DynamicMeta => { + REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME + }, EsdtTokenType::Invalid => "", }; diff --git a/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs index 4af1f5b9b2..54b685e61d 100644 --- a/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs @@ -187,26 +187,24 @@ where let token_type_name = match token_type { EsdtTokenType::Fungible => "FNG", - EsdtTokenType::NonFungible => "NFT", - EsdtTokenType::SemiFungible => "SFT", - EsdtTokenType::Meta => "META", - EsdtTokenType::NonFungibleV2 => "NFT", - EsdtTokenType::DynamicNFT => "NFT", - EsdtTokenType::DynamicSFT => "SFT", - EsdtTokenType::DynamicMeta => "META", + EsdtTokenType::NonFungible + | EsdtTokenType::NonFungibleV2 + | EsdtTokenType::DynamicNFT => "NFT", + EsdtTokenType::SemiFungible | EsdtTokenType::DynamicSFT => "SFT", + EsdtTokenType::Meta | EsdtTokenType::DynamicMeta => "META", EsdtTokenType::Invalid => "", }; let endpoint = match token_type { EsdtTokenType::Fungible | EsdtTokenType::NonFungible + | EsdtTokenType::NonFungibleV2 | EsdtTokenType::SemiFungible | EsdtTokenType::Meta => ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME, - EsdtTokenType::NonFungibleV2 - | EsdtTokenType::DynamicNFT - | EsdtTokenType::DynamicSFT - | EsdtTokenType::DynamicMeta => REGISTER_AND_SET_ALL_ROLES_DYNAMIC_ESDT_ENDPOINT_NAME, + EsdtTokenType::DynamicNFT | EsdtTokenType::DynamicSFT | EsdtTokenType::DynamicMeta => { + REGISTER_AND_SET_ALL_ROLES_DYNAMIC_ESDT_ENDPOINT_NAME + }, EsdtTokenType::Invalid => "", }; @@ -232,13 +230,14 @@ where let endpoint_name = match token_type { EsdtTokenType::Fungible => ISSUE_FUNGIBLE_ENDPOINT_NAME, - EsdtTokenType::NonFungible => ISSUE_NON_FUNGIBLE_ENDPOINT_NAME, + EsdtTokenType::NonFungible | EsdtTokenType::NonFungibleV2 => { + ISSUE_NON_FUNGIBLE_ENDPOINT_NAME + }, EsdtTokenType::SemiFungible => ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::Meta => REGISTER_META_ESDT_ENDPOINT_NAME, - EsdtTokenType::NonFungibleV2 - | EsdtTokenType::DynamicNFT - | EsdtTokenType::DynamicSFT - | EsdtTokenType::DynamicMeta => REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME, + EsdtTokenType::DynamicNFT | EsdtTokenType::DynamicSFT | EsdtTokenType::DynamicMeta => { + REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME + }, EsdtTokenType::Invalid => "", }; From 259a4fbd05d612f3019ca8a2e3bc05a844acbc54 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Sat, 30 Nov 2024 14:17:43 +0200 Subject: [PATCH 053/133] test - update multi payments w egld --- .../interact/src/bf_interact.rs | 52 ------------------- .../interact/tests/bf_interact_cs_test.rs | 1 - .../tests/basic_features_scenario_go_test.rs | 5 -- .../tests/basic_features_scenario_rs_test.rs | 6 --- .../scenarios/call-value-check.scen.json | 8 ++- .../scenarios/payable_multi_array.scen.json | 11 ++-- .../scenarios/payable_multiple.scen.json | 10 +++- .../tests/multi_transfer_with_egld.rs | 10 ++++ .../multi_transfer_with_egld.scen.json | 0 9 files changed, 32 insertions(+), 71 deletions(-) create mode 100644 framework/scenario/tests/multi_transfer_with_egld.rs rename {contracts/feature-tests/basic-features/scenarios => framework/scenario/tests/scenarios-self}/multi_transfer_with_egld.scen.json (100%) diff --git a/contracts/feature-tests/basic-features/interact/src/bf_interact.rs b/contracts/feature-tests/basic-features/interact/src/bf_interact.rs index 85c0cf8abd..665fa24fc8 100644 --- a/contracts/feature-tests/basic-features/interact/src/bf_interact.rs +++ b/contracts/feature-tests/basic-features/interact/src/bf_interact.rs @@ -306,56 +306,4 @@ impl BasicFeaturesInteract { }, } } - - pub async fn multi_transfer_with_egld(&mut self) { - let alice = self.interactor.register_wallet(test_wallets::alice()).await; - - let mut payments = ManagedVec::from(( - TokenIdentifier::from_esdt_bytes(b"EGLD-000000").clone(), - 0, - BigUint::from(50000000000000000u64), - )); - - let token = self - .interactor - .tx() - .from(&self.wallet_address) - .to(ESDTSystemSCAddress) - .gas(100_000_000u64) - .typed(ESDTSystemSCProxy) - .issue_fungible( - BigUint::from(50000000000000000u64), - "test", - "TEST", - BigUint::from(100usize), - FungibleTokenProperties { - num_decimals: 0usize, - can_freeze: true, - can_wipe: true, - can_pause: true, - can_mint: true, - can_burn: true, - can_change_owner: true, - can_upgrade: true, - can_add_special_roles: true, - }, - ) - .returns(ReturnsNewTokenIdentifier) - .run() - .await; - - payments.push(EsdtTokenPayment::new( - TokenIdentifier::from_esdt_bytes(token).clone(), - 0, - BigUint::from(10u32), - )); - - self.interactor - .tx() - .from(&self.wallet_address) - .to(alice) - .payment(payments) - .run() - .await; - } } diff --git a/contracts/feature-tests/basic-features/interact/tests/bf_interact_cs_test.rs b/contracts/feature-tests/basic-features/interact/tests/bf_interact_cs_test.rs index e9b3d70b74..57702b5160 100644 --- a/contracts/feature-tests/basic-features/interact/tests/bf_interact_cs_test.rs +++ b/contracts/feature-tests/basic-features/interact/tests/bf_interact_cs_test.rs @@ -16,7 +16,6 @@ async fn simulator_basic_features_test() { assert_eq!(bf_interact.large_storage_payload, data); bf_interact.deploy().await; - bf_interact.multi_transfer_with_egld().await; let expected_return_egld_decimal = ManagedDecimal::>::const_decimals_from_raw(BigUint::from( diff --git a/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs index b1717b0efc..02032a2126 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs @@ -187,11 +187,6 @@ fn echo_u_64_go() { world().run("scenarios/echo_u64.scen.json"); } -#[test] -fn multi_transfer_with_egld_go() { - world().run("scenarios/multi_transfer_with_egld.scen.json"); -} - #[test] fn echo_usize_go() { world().run("scenarios/echo_usize.scen.json"); diff --git a/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs index 0ab2459561..a4efa924ab 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs @@ -207,12 +207,6 @@ fn echo_u_64_rs() { world().run("scenarios/echo_u64.scen.json"); } -#[test] -#[ignore = "not supported yet"] -fn multi_transfer_with_egld_rs() { - world().run("scenarios/multi_transfer_with_egld.scen.json"); -} - #[test] fn echo_usize_rs() { world().run("scenarios/echo_usize.scen.json"); diff --git a/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json b/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json index 23da3773d6..8490c055fe 100644 --- a/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json @@ -86,6 +86,10 @@ "from": "address:an-account", "to": "sc:payable-features", "esdtValue": [ + { + "tokenIdentifier": "str:EGLD-000000", + "value": "15" + }, { "tokenIdentifier": "str:TOK-123456", "value": "100" @@ -107,7 +111,7 @@ }, "expect": { "out": [ - "0", + "15", [ "nested:str:TOK-123456|u64:0|biguint:100", "nested:str:OTHERTOK-123456|u64:0|biguint:400", @@ -121,4 +125,4 @@ } } ] -} +} \ No newline at end of file diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json index b05028dfae..16fa1cea20 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json @@ -52,6 +52,11 @@ "tokenIdentifier": "str:SFT-123", "nonce": "5", "value": "10" + }, + { + "tokenIdentifier": "str:EGLD-000000", + "nonce": "0", + "value": "103" } ], "function": "payment_array_3", @@ -111,7 +116,7 @@ "value": "100" }, { - "tokenIdentifier": "str:TOK-000002", + "tokenIdentifier": "str:EGLD-000000", "value": "400" }, { @@ -128,7 +133,7 @@ "expect": { "out": [ "nested:str:TOK-000001|u64:0|biguint:100", - "nested:str:TOK-000002|u64:0|biguint:400", + "nested:str:EGLD-000000|u64:0|biguint:400", "nested:str:SFT-123|u64:5|biguint:10" ], "status": "", @@ -138,4 +143,4 @@ } } ] -} +} \ No newline at end of file diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json index 45d92e9fa7..28e667b322 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json @@ -47,6 +47,11 @@ "tokenIdentifier": "str:SFT-123", "nonce": "5", "value": "10" + }, + { + "tokenIdentifier": "str:EGLD-000000", + "nonce": "0", + "value": "120" } ], "function": "payment_multiple", @@ -59,7 +64,8 @@ [ "nested:str:TOK-123456|u64:0|biguint:100|", "nested:str:OTHERTOK-123456|u64:0|biguint:400", - "nested:str:SFT-123|u64:5|biguint:10" + "nested:str:SFT-123|u64:5|biguint:10", + "nested:str:EGLD-000000|u64:0|biguint:120" ] ], "status": "", @@ -69,4 +75,4 @@ } } ] -} +} \ No newline at end of file diff --git a/framework/scenario/tests/multi_transfer_with_egld.rs b/framework/scenario/tests/multi_transfer_with_egld.rs new file mode 100644 index 0000000000..fdc5d0ffa4 --- /dev/null +++ b/framework/scenario/tests/multi_transfer_with_egld.rs @@ -0,0 +1,10 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + ScenarioWorld::vm_go() +} + +#[test] +fn multi_transfer_with_egld_test() { + world().run("tests/scenarios-self/multi_transfer_with_egld.scen.json"); +} diff --git a/contracts/feature-tests/basic-features/scenarios/multi_transfer_with_egld.scen.json b/framework/scenario/tests/scenarios-self/multi_transfer_with_egld.scen.json similarity index 100% rename from contracts/feature-tests/basic-features/scenarios/multi_transfer_with_egld.scen.json rename to framework/scenario/tests/scenarios-self/multi_transfer_with_egld.scen.json From 1b32b5357f2fb6633a30f432e9d449a3ee882e51 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Mon, 2 Dec 2024 12:39:11 +0200 Subject: [PATCH 054/133] test - forwarder multi transfer, multi transfer --- ...warder_call_async_multi_transfer.scen.json | 13 +- .../src/api/managed_types/const_handles.rs | 4 +- .../multi-transfer-esdt.scen.json | 14 +- .../scenario/tests/scenarios_self_go_test.rs | 181 ++++++++++++++++++ ...self_test.rs => scenarios_self_rs_test.rs} | 0 5 files changed, 200 insertions(+), 12 deletions(-) create mode 100644 framework/scenario/tests/scenarios_self_go_test.rs rename framework/scenario/tests/{scenarios_self_test.rs => scenarios_self_rs_test.rs} (100%) diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json index 81b18ee338..7dc86ee64f 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json @@ -10,7 +10,7 @@ }, "sc:forwarder": { "nonce": "0", - "balance": "0", + "balance": "4000", "esdt": { "str:FWD-TOKEN": "1000", "str:NFT-123456": { @@ -89,7 +89,7 @@ }, "sc:forwarder": { "nonce": "0", - "balance": "0", + "balance": "4000", "esdt": { "str:FWD-TOKEN": "700", "str:NFT-123456": { @@ -130,6 +130,9 @@ "str:NFT-123456", "1", "1", + "str:EGLD-000000", + "0", + "100", "str:SFT-456789", "3", "6" @@ -156,7 +159,7 @@ }, "sc:vault": { "nonce": "0", - "balance": "0", + "balance": "100", "esdt": { "str:FWD-TOKEN": "800", "str:NFT-123456": { @@ -183,7 +186,7 @@ }, "sc:forwarder": { "nonce": "0", - "balance": "0", + "balance": "3900", "esdt": { "str:FWD-TOKEN": "200", "str:SFT-456789": { @@ -200,4 +203,4 @@ } } ] -} +} \ No newline at end of file diff --git a/framework/base/src/api/managed_types/const_handles.rs b/framework/base/src/api/managed_types/const_handles.rs index 283d9c55c6..50b418ec93 100644 --- a/framework/base/src/api/managed_types/const_handles.rs +++ b/framework/base/src/api/managed_types/const_handles.rs @@ -8,7 +8,7 @@ pub const UNINITIALIZED_HANDLE: RawHandle = i32::MAX; /// WARNING! With the current VM this still needs to be initialized before use. pub const BIG_INT_CONST_ZERO: RawHandle = -10; -pub const CALL_VALUE_EGLD: RawHandle = -11; +pub const CALL_VALUE_EGLD: RawHandle = -11; // useful pub const CALL_VALUE_SINGLE_ESDT: RawHandle = -13; pub const BIG_INT_TEMPORARY_1: RawHandle = -14; @@ -17,7 +17,7 @@ pub const BIG_FLOAT_TEMPORARY: RawHandle = -16; /// WARNING! With the current VM this still needs to be initialized before use. pub const MBUF_CONST_EMPTY: RawHandle = -20; -pub const CALL_VALUE_MULTI_ESDT: RawHandle = -21; +pub const CALL_VALUE_MULTI_ESDT: RawHandle = -21; // useful pub const CALL_VALUE_SINGLE_ESDT_TOKEN_NAME: RawHandle = -22; pub const CALLBACK_CLOSURE_ARGS_BUFFER: RawHandle = -23; pub const MBUF_TEMPORARY_1: RawHandle = -25; diff --git a/framework/scenario/tests/scenarios-self/multi-transfer-esdt.scen.json b/framework/scenario/tests/scenarios-self/multi-transfer-esdt.scen.json index 3b1095be7a..9aad78288d 100644 --- a/framework/scenario/tests/scenarios-self/multi-transfer-esdt.scen.json +++ b/framework/scenario/tests/scenarios-self/multi-transfer-esdt.scen.json @@ -6,7 +6,7 @@ "accounts": { "address:A": { "nonce": "0", - "balance": "0x1000000000", + "balance": "1000000000", "esdt": { "str:TOK-123456": "150", "str:OTHERTOK-123456": "500", @@ -41,14 +41,17 @@ "tokenIdentifier": "str:OTHERTOK-123456", "value": "400" }, + { + "tokenIdentifier": "str:EGLD-000000", + "value": "500" + }, { "tokenIdentifier": "str:NFT-123456", "nonce": "5", "value": "10" } ], - "gasLimit": "0x100000000", - "gasPrice": "0x01" + "gasLimit": "0x100000000" } }, { @@ -57,7 +60,7 @@ "accounts": { "address:A": { "nonce": "1", - "balance": "0xf00000000", + "balance": "999999500", "esdt": { "str:TOK-123456": "50", "str:OTHERTOK-123456": "100", @@ -75,6 +78,7 @@ }, "address:B": { "nonce": "0", + "balance": "500", "esdt": { "str:TOK-123456": "100", "str:OTHERTOK-123456": "400", @@ -93,4 +97,4 @@ } } ] -} +} \ No newline at end of file diff --git a/framework/scenario/tests/scenarios_self_go_test.rs b/framework/scenario/tests/scenarios_self_go_test.rs new file mode 100644 index 0000000000..87bb7ae7c5 --- /dev/null +++ b/framework/scenario/tests/scenarios_self_go_test.rs @@ -0,0 +1,181 @@ +use multiversx_sc_scenario::*; + +// These tests don't really test any contract, but the testing framework itself. + +fn world() -> ScenarioWorld { + ScenarioWorld::vm_go() +} + +/// Checks that externalSteps work fine. +#[test] +fn external_steps_go() { + world().run("tests/scenarios-self/external_steps/external_steps.scen.json"); +} + +#[test] +#[should_panic] +fn set_account_addr_len_err1_go() { + world().run("tests/scenarios-self/set-check/set-account-addr-len.err1.json"); +} + +#[test] +#[should_panic] +fn set_account_addr_len_err2_go() { + world().run("tests/scenarios-self/set-check/set-account-addr-len.err2.json"); +} + +#[test] +#[should_panic] +fn set_account_sc_addr_err1_go() { + world().run("tests/scenarios-self/set-check/set-account-sc-addr.err1.json"); +} + +#[test] +#[should_panic] +fn set_account_sc_addr_err2_go() { + world().run("tests/scenarios-self/set-check/set-account-sc-addr.err2.json"); +} + +#[test] +#[should_panic] +fn set_account_sc_addr_err3_go() { + world().run("tests/scenarios-self/set-check/set-account-sc-addr.err3.json"); +} + +#[test] +#[should_panic] +fn set_check_balance_err_go() { + world().run("tests/scenarios-self/set-check/set-check-balance.err.json"); +} + +#[test] +fn set_check_balance_go() { + world().run("tests/scenarios-self/set-check/set-check-balance.scen.json"); +} + +#[test] +#[should_panic] +fn set_check_code_err_go() { + world().run("tests/scenarios-self/set-check/set-check-code.err.json"); +} + +#[test] +fn set_check_code() { + world().run("tests/scenarios-self/set-check/set-check-code.scen.json"); +} + +#[test] +#[should_panic] +fn set_check_codemetadata_err_go() { + world().run("tests/scenarios-self/set-check/set-check-codemetadata.err.json"); +} + +#[test] +fn set_check_codemetadata() { + world().run("tests/scenarios-self/set-check/set-check-codemetadata.scen.json"); +} + +#[test] +#[should_panic] +fn set_check_esdt_err_go() { + world().run("tests/scenarios-self/set-check/set-check-esdt.err1.json"); +} + +#[test] +fn set_check_esdt_go() { + world().run("tests/scenarios-self/set-check/set-check-esdt.scen.json"); +} + +#[test] +#[should_panic] +fn set_check_nonce_err_go() { + world().run("tests/scenarios-self/set-check/set-check-nonce.err.json"); +} + +#[test] +fn set_check_nonce_go() { + world().run("tests/scenarios-self/set-check/set-check-nonce.scen.json"); +} + +#[test] +#[should_panic] +fn set_check_storage_err1_go() { + world().run("tests/scenarios-self/set-check/set-check-storage.err1.json"); +} + +#[test] +#[should_panic] +fn set_check_storage_err2_go() { + world().run("tests/scenarios-self/set-check/set-check-storage.err2.json"); +} + +#[test] +#[should_panic] +fn set_check_storage_err3_go() { + world().run("tests/scenarios-self/set-check/set-check-storage.err3.json"); +} + +#[test] +#[should_panic] +fn set_check_storage_err4_go() { + world().run("tests/scenarios-self/set-check/set-check-storage.err4.json"); +} + +#[test] +#[should_panic] +fn set_check_storage_err5_go() { + world().run("tests/scenarios-self/set-check/set-check-storage.err5.json"); +} + +#[test] +fn set_check_storage_go() { + world().run("tests/scenarios-self/set-check/set-check-storage.scen.json"); +} + +#[test] +#[should_panic] +fn set_check_username_err_go() { + world().run("tests/scenarios-self/set-check/set-check-username.err.json"); +} + +#[test] +fn set_check_username_go() { + world().run("tests/scenarios-self/set-check/set-check-username.scen.json"); +} + +#[test] +fn builtin_func_esdt_transfer() { + world().run("tests/scenarios-self/builtin-func-esdt-transfer.scen.json"); +} + +#[test] +#[should_panic] +fn esdt_non_zero_balance_check_err_go() { + world().run("tests/scenarios-self/esdt-non-zero-balance-check-err.scen.json"); +} + +#[test] +#[should_panic] +fn esdt_zero_balance_check_err_go() { + world().run("tests/scenarios-self/esdt-zero-balance-check-err.scen.json"); +} + +#[test] +fn multi_transfer_esdt_go() { + world().run("tests/scenarios-self/multi-transfer-esdt.scen.json"); +} + +#[test] +fn transfer_egld_go() { + world().run("tests/scenarios-self/transfer-egld.scen.json"); +} + +#[test] +fn transfer_esdt_go() { + world().run("tests/scenarios-self/transfer-esdt.scen.json"); +} + +#[test] +fn validator_reward_go() { + world().run("tests/scenarios-self/validatorReward.scen.json"); +} diff --git a/framework/scenario/tests/scenarios_self_test.rs b/framework/scenario/tests/scenarios_self_rs_test.rs similarity index 100% rename from framework/scenario/tests/scenarios_self_test.rs rename to framework/scenario/tests/scenarios_self_rs_test.rs From e8660384d9c5d80cecb74974ec8ac532eb611556 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Mon, 2 Dec 2024 12:41:24 +0200 Subject: [PATCH 055/133] cleanup --- framework/base/src/api/managed_types/const_handles.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/base/src/api/managed_types/const_handles.rs b/framework/base/src/api/managed_types/const_handles.rs index 50b418ec93..283d9c55c6 100644 --- a/framework/base/src/api/managed_types/const_handles.rs +++ b/framework/base/src/api/managed_types/const_handles.rs @@ -8,7 +8,7 @@ pub const UNINITIALIZED_HANDLE: RawHandle = i32::MAX; /// WARNING! With the current VM this still needs to be initialized before use. pub const BIG_INT_CONST_ZERO: RawHandle = -10; -pub const CALL_VALUE_EGLD: RawHandle = -11; // useful +pub const CALL_VALUE_EGLD: RawHandle = -11; pub const CALL_VALUE_SINGLE_ESDT: RawHandle = -13; pub const BIG_INT_TEMPORARY_1: RawHandle = -14; @@ -17,7 +17,7 @@ pub const BIG_FLOAT_TEMPORARY: RawHandle = -16; /// WARNING! With the current VM this still needs to be initialized before use. pub const MBUF_CONST_EMPTY: RawHandle = -20; -pub const CALL_VALUE_MULTI_ESDT: RawHandle = -21; // useful +pub const CALL_VALUE_MULTI_ESDT: RawHandle = -21; pub const CALL_VALUE_SINGLE_ESDT_TOKEN_NAME: RawHandle = -22; pub const CALLBACK_CLOSURE_ARGS_BUFFER: RawHandle = -23; pub const MBUF_TEMPORARY_1: RawHandle = -25; From d1095ad25973548f52a65500f39f1422a30d9555 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Mon, 2 Dec 2024 15:52:09 +0200 Subject: [PATCH 056/133] unified - payable blackbox --- .../payable-features/src/payable_features.rs | 4 +- .../src/payable_features_proxy.rs | 184 ++++++++++++++++++ .../tests/payable_blackbox_test.rs | 71 ++++--- 3 files changed, 230 insertions(+), 29 deletions(-) create mode 100644 contracts/feature-tests/payable-features/src/payable_features_proxy.rs diff --git a/contracts/feature-tests/payable-features/src/payable_features.rs b/contracts/feature-tests/payable-features/src/payable_features.rs index d8296f8592..37fe3f0c9d 100644 --- a/contracts/feature-tests/payable-features/src/payable_features.rs +++ b/contracts/feature-tests/payable-features/src/payable_features.rs @@ -1,7 +1,9 @@ #![no_std] #![allow(clippy::type_complexity)] -multiversx_sc::imports!(); +use multiversx_sc::imports::*; + +pub mod payable_features_proxy; /// Contract that only tests the call value features, /// i.e. the framework/Arwen functionality for accepting EGLD and ESDT payments. diff --git a/contracts/feature-tests/payable-features/src/payable_features_proxy.rs b/contracts/feature-tests/payable-features/src/payable_features_proxy.rs new file mode 100644 index 0000000000..7d6e020c89 --- /dev/null +++ b/contracts/feature-tests/payable-features/src/payable_features_proxy.rs @@ -0,0 +1,184 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct PayableFeaturesProxy; + +impl TxProxyTrait for PayableFeaturesProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = PayableFeaturesProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + PayableFeaturesProxyMethods { wrapped_tx: tx } + } +} + +pub struct PayableFeaturesProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl PayableFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl PayableFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn echo_call_value( + self, + ) -> TxTypedCall, ManagedVec>>> { + self.wrapped_tx + .raw_call("echo_call_value") + .original_result() + } + + pub fn payment_multiple( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .raw_call("payment_multiple") + .original_result() + } + + pub fn payment_array_3( + self, + ) -> TxTypedCall, EsdtTokenPayment, EsdtTokenPayment>> { + self.wrapped_tx + .raw_call("payment_array_3") + .original_result() + } + + pub fn payable_any_1( + self, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_any_1") + .original_result() + } + + pub fn payable_any_2( + self, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_any_2") + .original_result() + } + + pub fn payable_any_3( + self, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_any_3") + .original_result() + } + + pub fn payable_any_4( + self, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_any_4") + .original_result() + } + + pub fn payable_egld_1( + self, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_egld_1") + .original_result() + } + + pub fn payable_egld_2( + self, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_egld_2") + .original_result() + } + + pub fn payable_egld_3( + self, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_egld_3") + .original_result() + } + + pub fn payable_egld_4( + self, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_egld_4") + .original_result() + } + + pub fn payable_token_1( + self, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_token_1") + .original_result() + } + + pub fn payable_token_2( + self, + ) -> TxTypedCall, TokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_token_2") + .original_result() + } + + pub fn payable_token_3( + self, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_token_3") + .original_result() + } + + pub fn payable_token_4( + self, + ) -> TxTypedCall, TokenIdentifier>> { + self.wrapped_tx + .raw_call("payable_token_4") + .original_result() + } +} diff --git a/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs b/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs index 44aa98c1b5..b56dc46aaa 100644 --- a/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs +++ b/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs @@ -1,6 +1,13 @@ use multiversx_sc_scenario::imports::*; +use payable_features::payable_features_proxy; -const PF_PATH_EXPR: &str = "mxsc:output/payable-features.mxsc.json"; +const PF_PATH_EXPR: MxscPath = MxscPath::new("output/payable-features.mxsc.json"); +const PAYABLE_FEATURES_ADDRESS: TestSCAddress = TestSCAddress::new("payable-features"); +const USER: TestAddress = TestAddress::new("an-account"); +const TOKEN_1: TestTokenIdentifier = TestTokenIdentifier::new("TOK-000001"); +const TOKEN_2: TestTokenIdentifier = TestTokenIdentifier::new("TOK-000002"); +const TOKEN_3: TestTokenIdentifier = TestTokenIdentifier::new("TOK-000003"); +const SFT: TestTokenIdentifier = TestTokenIdentifier::new("SFT-123"); fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); @@ -13,33 +20,41 @@ fn world() -> ScenarioWorld { #[test] fn payable_multi() { let mut world = world(); - let pf_code = world.code_expression(PF_PATH_EXPR); world - .set_state_step( - SetStateStep::new() - .put_account("sc:payable-features", Account::new().code(pf_code)) - .put_account( - "address:an-account", - Account::new() - .balance("10000") - .esdt_balance("str:TOK-000001", "1000") - .esdt_balance("str:TOK-000002", "500") - .esdt_balance("str:TOK-000003", "500") - .esdt_nft_balance("str:SFT-123", 5u32, 10u32, Option::<()>::None) - ), - ) - .sc_call( - ScCallStep::new() - .from("address:an-account") - .to("sc:payable-features") - .function("echo_call_value") - .esdt_transfer("str:TOK-000001", 0, "100") - .esdt_transfer("str:TOK-000002", 0, "400") - .expect( - TxExpect::ok() - .result("0") - .result("nested:str:TOK-000001|u64:0|biguint:100|nested:str:TOK-000002|u64:0|biguint:400") - ), - ); + .account(USER) + .balance(10000) + .esdt_balance(TOKEN_1, 1000) + .esdt_balance(TOKEN_2, 500) + .esdt_balance(TOKEN_3, 500) + .esdt_nft_balance(SFT, 5, 10, ()); + + world + .tx() + .from(USER) + .typed(payable_features_proxy::PayableFeaturesProxy) + .init() + .new_address(PAYABLE_FEATURES_ADDRESS) + .code(PF_PATH_EXPR) + .run(); + + let result = world + .tx() + .from(USER) + .to(PAYABLE_FEATURES_ADDRESS) + .typed(payable_features_proxy::PayableFeaturesProxy) + .echo_call_value() + .esdt(TestEsdtTransfer(TOKEN_1, 0, 100)) + .esdt(TestEsdtTransfer(TOKEN_2, 0, 400)) + .returns(ReturnsResultUnmanaged) + .run(); + + assert_eq!(result.0 .0, RustBigUint::from(0u32)); + assert_eq!( + result.0 .1, + vec![ + EsdtTokenPayment::new(TOKEN_1.to_token_identifier(), 0, BigUint::from(100u32)), + EsdtTokenPayment::new(TOKEN_2.to_token_identifier(), 0, BigUint::from(400u32)) + ] + ); } From 1401103b3789a6bde8b9a16941c477057903717a Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Mon, 2 Dec 2024 16:28:40 +0200 Subject: [PATCH 057/133] insert payable token test --- .../scenarios/payable_token_5.scen.json | 120 ++++++++++++++++++ .../tests/payable_scenario_go_test.rs | 5 + .../tests/payable_scenario_rs_test.rs | 5 + 3 files changed, 130 insertions(+) create mode 100644 contracts/feature-tests/payable-features/scenarios/payable_token_5.scen.json diff --git a/contracts/feature-tests/payable-features/scenarios/payable_token_5.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_token_5.scen.json new file mode 100644 index 0000000000..6193d505e4 --- /dev/null +++ b/contracts/feature-tests/payable-features/scenarios/payable_token_5.scen.json @@ -0,0 +1,120 @@ +{ + "name": "payable", + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:payable-features": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/payable-features.mxsc.json", + "codeMetadata": "0x0000" + }, + "address:an-account": { + "nonce": "0", + "balance": "1,000,000,000,000", + "esdt": { + "str:PAYABLE-FEATURES-TOKEN": "1,000,000,000,000", + "str:OTHER-TOKEN": "1,000,000,000,000" + } + } + } + }, + { + "step": "scCall", + "id": "payable_token_1.1", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "function": "payable_token_1", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:function expects single ESDT payment", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "payable_token_1.2", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "egldValue": "5", + "function": "payable_token_1", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:function expects single ESDT payment", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "payable_token_1.3", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:PAYABLE-FEATURES-TOKEN", + "value": "100" + } + ], + "function": "payable_token_1", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x64", + "0x50415941424c452d46454154555245532d544f4b454e" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "payable_token_1.4", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:OTHER-TOKEN", + "value": "100" + } + ], + "function": "payable_token_1", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:bad call value token provided", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} \ No newline at end of file diff --git a/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs b/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs index 58db78cf8f..a3ababd9c7 100644 --- a/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs +++ b/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs @@ -78,3 +78,8 @@ fn payable_token_3_go() { fn payable_token_4_go() { world().run("scenarios/payable_token_4.scen.json"); } + +#[test] +fn payable_token_5_go() { + world().run("scenarios/payable_token_5.scen.json"); +} diff --git a/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs b/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs index 4e88c1cd75..01b0ea567b 100644 --- a/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs +++ b/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs @@ -84,3 +84,8 @@ fn payable_token_3_rs() { fn payable_token_4_rs() { world().run("scenarios/payable_token_4.scen.json"); } + +#[test] +fn payable_token_5_rs() { + world().run("scenarios/payable_token_5.scen.json"); +} From 20f60369d7952740cc51c6f34fa08f828363a736 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Mon, 2 Dec 2024 16:18:38 +0100 Subject: [PATCH 058/133] remove nftv2 --- chain/core/src/types/flags/esdt_token_type.rs | 21 +++++++------------ .../system_proxy/esdt_system_sc_proxy.rs | 10 ++------- .../system_proxy/legacy_system_sc_proxy.rs | 9 ++------ 3 files changed, 11 insertions(+), 29 deletions(-) diff --git a/chain/core/src/types/flags/esdt_token_type.rs b/chain/core/src/types/flags/esdt_token_type.rs index bfa2b07192..bfa65f604a 100644 --- a/chain/core/src/types/flags/esdt_token_type.rs +++ b/chain/core/src/types/flags/esdt_token_type.rs @@ -9,7 +9,6 @@ const ESDT_TYPE_FUNGIBLE: &[u8] = b"FungibleESDT"; const ESDT_TYPE_NON_FUNGIBLE: &[u8] = b"NonFungibleESDT"; const ESDT_TYPE_SEMI_FUNGIBLE: &[u8] = b"SemiFungibleESDT"; const ESDT_TYPE_META: &[u8] = b"MetaESDT"; -const ESDT_TYPE_NON_FUNGIBLE_V2: &[u8] = b"NonFungibleESDTv2"; const ESDT_TYPE_DYNAMIC_NON_FUNGIBLE: &[u8] = b"DynamicNonFungibleESDT"; const ESDT_TYPE_DYNAMIC_SEMI_FUNGIBLE: &[u8] = b"DynamicSemiFungibleESDT"; const ESDT_TYPE_DYNAMIC_META: &[u8] = b"DynamicMetaESDT"; @@ -23,7 +22,6 @@ pub enum EsdtTokenType { NonFungible, SemiFungible, Meta, - NonFungibleV2, DynamicNFT, DynamicSFT, DynamicMeta, @@ -45,11 +43,10 @@ impl EsdtTokenType { Self::NonFungible => 1, Self::SemiFungible => 2, Self::Meta => 3, - Self::NonFungibleV2 => 4, - Self::DynamicNFT => 5, - Self::DynamicSFT => 6, - Self::DynamicMeta => 7, - Self::Invalid => 8, + Self::DynamicNFT => 4, + Self::DynamicSFT => 5, + Self::DynamicMeta => 6, + Self::Invalid => 7, } } @@ -59,7 +56,6 @@ impl EsdtTokenType { Self::NonFungible => ESDT_TYPE_NON_FUNGIBLE, Self::SemiFungible => ESDT_TYPE_SEMI_FUNGIBLE, Self::Meta => ESDT_TYPE_META, - Self::NonFungibleV2 => ESDT_TYPE_NON_FUNGIBLE_V2, Self::DynamicNFT => ESDT_TYPE_DYNAMIC_NON_FUNGIBLE, Self::DynamicSFT => ESDT_TYPE_DYNAMIC_SEMI_FUNGIBLE, Self::DynamicMeta => ESDT_TYPE_DYNAMIC_META, @@ -76,10 +72,9 @@ impl From for EsdtTokenType { 1 => Self::NonFungible, 2 => Self::SemiFungible, 3 => Self::Meta, - 4 => Self::NonFungibleV2, - 5 => Self::DynamicNFT, - 6 => Self::DynamicSFT, - 7 => Self::DynamicMeta, + 4 => Self::DynamicNFT, + 5 => Self::DynamicSFT, + 6 => Self::DynamicMeta, _ => Self::Invalid, } } @@ -96,8 +91,6 @@ impl<'a> From<&'a [u8]> for EsdtTokenType { Self::SemiFungible } else if byte_slice == ESDT_TYPE_META { Self::Meta - } else if byte_slice == ESDT_TYPE_NON_FUNGIBLE_V2 { - Self::NonFungibleV2 } else if byte_slice == ESDT_TYPE_DYNAMIC_NON_FUNGIBLE { Self::DynamicNFT } else if byte_slice == ESDT_TYPE_DYNAMIC_SEMI_FUNGIBLE { diff --git a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs index 87e4e1fd7b..ccea8494d3 100644 --- a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs @@ -213,9 +213,7 @@ where ) -> IssueCall { let token_type_name = match token_type { EsdtTokenType::Fungible => "FNG", - EsdtTokenType::NonFungible - | EsdtTokenType::NonFungibleV2 - | EsdtTokenType::DynamicNFT => "NFT", + EsdtTokenType::NonFungible | EsdtTokenType::DynamicNFT => "NFT", EsdtTokenType::SemiFungible | EsdtTokenType::DynamicSFT => "SFT", EsdtTokenType::Meta | EsdtTokenType::DynamicMeta => "META", EsdtTokenType::Invalid => "", @@ -224,10 +222,8 @@ where let endpoint = match token_type { EsdtTokenType::Fungible | EsdtTokenType::NonFungible - | EsdtTokenType::NonFungibleV2 | EsdtTokenType::SemiFungible | EsdtTokenType::Meta => ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME, - EsdtTokenType::DynamicNFT | EsdtTokenType::DynamicSFT | EsdtTokenType::DynamicMeta => { REGISTER_AND_SET_ALL_ROLES_DYNAMIC_ESDT_ENDPOINT_NAME }, @@ -261,9 +257,7 @@ where ) -> IssueCall { let endpoint_name = match token_type { EsdtTokenType::Fungible => ISSUE_FUNGIBLE_ENDPOINT_NAME, - EsdtTokenType::NonFungible | EsdtTokenType::NonFungibleV2 => { - ISSUE_NON_FUNGIBLE_ENDPOINT_NAME - }, + EsdtTokenType::NonFungible => ISSUE_NON_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::SemiFungible => ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::Meta => REGISTER_META_ESDT_ENDPOINT_NAME, EsdtTokenType::DynamicNFT | EsdtTokenType::DynamicSFT | EsdtTokenType::DynamicMeta => { diff --git a/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs index 54b685e61d..a7cdeb4570 100644 --- a/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs @@ -187,9 +187,7 @@ where let token_type_name = match token_type { EsdtTokenType::Fungible => "FNG", - EsdtTokenType::NonFungible - | EsdtTokenType::NonFungibleV2 - | EsdtTokenType::DynamicNFT => "NFT", + EsdtTokenType::NonFungible | EsdtTokenType::DynamicNFT => "NFT", EsdtTokenType::SemiFungible | EsdtTokenType::DynamicSFT => "SFT", EsdtTokenType::Meta | EsdtTokenType::DynamicMeta => "META", EsdtTokenType::Invalid => "", @@ -198,7 +196,6 @@ where let endpoint = match token_type { EsdtTokenType::Fungible | EsdtTokenType::NonFungible - | EsdtTokenType::NonFungibleV2 | EsdtTokenType::SemiFungible | EsdtTokenType::Meta => ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME, @@ -230,9 +227,7 @@ where let endpoint_name = match token_type { EsdtTokenType::Fungible => ISSUE_FUNGIBLE_ENDPOINT_NAME, - EsdtTokenType::NonFungible | EsdtTokenType::NonFungibleV2 => { - ISSUE_NON_FUNGIBLE_ENDPOINT_NAME - }, + EsdtTokenType::NonFungible => ISSUE_NON_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::SemiFungible => ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::Meta => REGISTER_META_ESDT_ENDPOINT_NAME, EsdtTokenType::DynamicNFT | EsdtTokenType::DynamicSFT | EsdtTokenType::DynamicMeta => { From 9831902322555e9bd7bb538a0b4d339be8129f59 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Mon, 2 Dec 2024 18:30:54 +0100 Subject: [PATCH 059/133] system interactor chain simulator setup --- tools/interactor-system-func-calls/Cargo.toml | 6 + .../src/system_sc_interact.rs | 230 ++++++++++++------ .../src/system_sc_interact_config.rs | 9 +- .../src/system_sc_main.rs | 6 + .../tests/chain_simulator_token_tests.rs | 54 ++++ 5 files changed, 229 insertions(+), 76 deletions(-) create mode 100644 tools/interactor-system-func-calls/src/system_sc_main.rs create mode 100644 tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs diff --git a/tools/interactor-system-func-calls/Cargo.toml b/tools/interactor-system-func-calls/Cargo.toml index a92170f220..28921639df 100644 --- a/tools/interactor-system-func-calls/Cargo.toml +++ b/tools/interactor-system-func-calls/Cargo.toml @@ -1,5 +1,8 @@ [[bin]] name = "system-sc-interact" +path = "src/system_sc_main.rs" + +[lib] path = "src/system_sc_interact.rs" [package] @@ -24,3 +27,6 @@ features = ["derive"] [dependencies.multiversx-sc-snippets] version = "=0.54.5" path = "../../framework/snippets" + +[features] +chain-simulator-tests = [] diff --git a/tools/interactor-system-func-calls/src/system_sc_interact.rs b/tools/interactor-system-func-calls/src/system_sc_interact.rs index 97d3005c97..a10e7caaec 100644 --- a/tools/interactor-system-func-calls/src/system_sc_interact.rs +++ b/tools/interactor-system-func-calls/src/system_sc_interact.rs @@ -1,21 +1,18 @@ -#![allow(deprecated)] // TODO: move prepare_async calls to a test for backwards compatibility and delete from here - mod system_sc_interact_cli; mod system_sc_interact_config; mod system_sc_interact_state; use clap::Parser; -use system_sc_interact_cli::NftDummyAttributes; -use system_sc_interact_config::Config; +pub use system_sc_interact_cli::NftDummyAttributes; +pub use system_sc_interact_config::Config; use system_sc_interact_state::State; use multiversx_sc_snippets::imports::*; -#[tokio::main] -async fn main() { +pub async fn system_sc_interact_cli() { env_logger::init(); - let mut basic_interact = SysFuncCallsInteract::init().await; + let mut basic_interact = SysFuncCallsInteract::init(Config::load_config()).await; let cli = system_sc_interact_cli::InteractCli::parse(); match &cli.command { @@ -130,6 +127,11 @@ async fn main() { args.name.as_bytes(), args.royalties, args.hash.as_bytes(), + &NftDummyAttributes { + creation_epoch: 2u64, + cool_factor: 3u8, + }, + Vec::new(), ) .await; }, @@ -219,19 +221,18 @@ async fn main() { } } -#[allow(unused)] -struct SysFuncCallsInteract { +pub struct SysFuncCallsInteract { interactor: Interactor, wallet_address: Bech32Address, + #[allow(unused)] state: State, } impl SysFuncCallsInteract { - async fn init() -> Self { - let config = Config::load_config(); + pub async fn init(config: Config) -> Self { let mut interactor = Interactor::new(config.gateway_uri()) .await - .use_chain_simulator(config.use_chain_simulator()); + .use_chain_simulator(config.is_chain_simulator()); interactor.set_current_dir_from_workspace("tools/interactor-system-func-calls"); let wallet_address = interactor.register_wallet(test_wallets::alice()).await; @@ -246,7 +247,7 @@ impl SysFuncCallsInteract { } } - async fn issue_fungible_token( + pub async fn issue_fungible_token( &mut self, issue_cost: RustBigUint, token_display_name: &[u8], @@ -281,14 +282,13 @@ impl SysFuncCallsInteract { }, ) .returns(ReturnsNewTokenIdentifier) - .prepare_async() .run() .await; println!("TOKEN ID: {:?}", res); } - async fn issue_non_fungible_collection( + pub async fn issue_non_fungible_collection( &mut self, issue_cost: RustBigUint, token_display_name: &[u8], @@ -318,14 +318,13 @@ impl SysFuncCallsInteract { }, ) .returns(ReturnsNewTokenIdentifier) - .prepare_async() .run() .await; println!("NFT Collection ID: {:?}", nft_collection_id); } - async fn issue_semi_fungible_collection( + pub async fn issue_semi_fungible_collection( &mut self, issue_cost: RustBigUint, token_display_name: &[u8], @@ -355,22 +354,21 @@ impl SysFuncCallsInteract { }, ) .returns(ReturnsNewTokenIdentifier) - .prepare_async() .run() .await; println!("SFT Collection ID: {:?}", sft_collection_id); } - async fn issue_token( + pub async fn issue_token( &mut self, issue_cost: RustBigUint, token_display_name: &[u8], token_ticker: &[u8], num_decimals: usize, token_type: EsdtTokenType, - ) { - println!("Registering token..."); + ) -> String { + println!("Registering and setting all roles for token {token_ticker:?} of type {token_type:?}..."); let token_id = self .interactor @@ -387,16 +385,17 @@ impl SysFuncCallsInteract { num_decimals, ) .returns(ReturnsNewTokenIdentifier) - .prepare_async() .run() .await; println!("TOKEN ID: {:?}", token_id); + + token_id } - async fn set_roles(&mut self, token_id: &[u8], roles: Vec) { + pub async fn set_roles(&mut self, token_id: &[u8], roles: Vec) { let wallet_address = &self.wallet_address.clone().into_address(); - println!("Setting the following roles: {:?}", roles); + println!("Setting the following roles: {roles:?} for {token_id:?}"); self.interactor .tx() @@ -409,12 +408,11 @@ impl SysFuncCallsInteract { TokenIdentifier::from(token_id), roles.into_iter(), ) - .prepare_async() .run() .await; } - async fn mint_sft( + pub async fn mint_sft( &mut self, token_id: &[u8], amount: RustBigUint, @@ -442,12 +440,11 @@ impl SysFuncCallsInteract { }, &ManagedVec::new(), ) - .prepare_async() .run() .await; } - async fn register_meta_esdt( + pub async fn register_meta_esdt( &mut self, issue_cost: RustBigUint, token_display_name: &[u8], @@ -479,14 +476,13 @@ impl SysFuncCallsInteract { }, ) .returns(ReturnsNewTokenIdentifier) - .prepare_async() .run() .await; println!("Meta-ESDT ID: {:?}", meta_esdt); } - async fn change_sft_meta_esdt(&mut self, token_id: &[u8], num_decimals: usize) { + pub async fn change_sft_meta_esdt(&mut self, token_id: &[u8], num_decimals: usize) { println!("Changing SFT to Meta-ESDT..."); self.interactor @@ -496,12 +492,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .change_sft_to_meta_esdt(token_id, num_decimals) - .prepare_async() .run() .await; } - async fn mint_token(&mut self, token_id: &[u8], nonce: u64, amount: RustBigUint) { + pub async fn mint_token(&mut self, token_id: &[u8], nonce: u64, amount: RustBigUint) { println!("Minting tokens..."); self.interactor @@ -511,12 +506,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(UserBuiltinProxy) .esdt_local_mint(token_id, nonce, amount) - .prepare_async() .run() .await; } - async fn burn_token(&mut self, token_id: &[u8], nonce: u64, amount: RustBigUint) { + pub async fn burn_token(&mut self, token_id: &[u8], nonce: u64, amount: RustBigUint) { println!("Burning tokens..."); self.interactor @@ -526,12 +520,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(UserBuiltinProxy) .esdt_local_burn(token_id, nonce, amount) - .prepare_async() .run() .await; } - async fn pause_token(&mut self, token_id: &[u8]) { + pub async fn pause_token(&mut self, token_id: &[u8]) { println!("Pausing token..."); self.interactor @@ -541,12 +534,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .pause(token_id) - .prepare_async() .run() .await; } - async fn unpause_token(&mut self, token_id: &[u8]) { + pub async fn unpause_token(&mut self, token_id: &[u8]) { println!("Unpausing token..."); self.interactor @@ -556,12 +548,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .unpause(token_id) - .prepare_async() .run() .await; } - async fn freeze_token(&mut self, token_id: &[u8], address: &Bech32Address) { + pub async fn freeze_token(&mut self, token_id: &[u8], address: &Bech32Address) { println!("Freezing token..."); self.interactor @@ -571,12 +562,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .freeze(token_id, address) - .prepare_async() .run() .await; } - async fn unfreeze_token(&mut self, token_id: &[u8], address: &Bech32Address) { + pub async fn unfreeze_token(&mut self, token_id: &[u8], address: &Bech32Address) { println!("Unfreezing token..."); self.interactor @@ -586,12 +576,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .unfreeze(token_id, address) - .prepare_async() .run() .await; } - async fn freeze_nft(&mut self, token_id: &[u8], nonce: u64, address: &Bech32Address) { + pub async fn freeze_nft(&mut self, token_id: &[u8], nonce: u64, address: &Bech32Address) { println!("Freezing NFT/SFT/Meta-ESDT..."); self.interactor @@ -601,12 +590,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .freeze_nft(token_id, nonce, address) - .prepare_async() .run() .await; } - async fn unfreeze_nft(&mut self, token_id: &[u8], nonce: u64, address: &Bech32Address) { + pub async fn unfreeze_nft(&mut self, token_id: &[u8], nonce: u64, address: &Bech32Address) { println!("Unfreezing NFT/SFT/Meta-ESDT..."); self.interactor @@ -616,12 +604,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .unfreeze_nft(token_id, nonce, address) - .prepare_async() .run() .await; } - async fn wipe_token(&mut self, token_id: &[u8], address: &Bech32Address) { + pub async fn wipe_token(&mut self, token_id: &[u8], address: &Bech32Address) { println!("Wiping token..."); self.interactor @@ -631,12 +618,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .wipe(token_id, address) - .prepare_async() .run() .await; } - async fn wipe_nft(&mut self, token_id: &[u8], nonce: u64, address: &Bech32Address) { + pub async fn wipe_nft(&mut self, token_id: &[u8], nonce: u64, address: &Bech32Address) { println!("Wiping NFT/SFT/Meta-ESDT..."); self.interactor @@ -646,45 +632,41 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .wipe_nft(token_id, nonce, address) - .prepare_async() .run() .await; } - async fn mint_nft( + #[allow(clippy::too_many_arguments)] + pub async fn mint_nft( &mut self, token_id: &[u8], amount: RustBigUint, name: &[u8], royalties: u64, hash: &[u8], - ) { + attributes: &T, + uris: Vec, + ) -> u64 { println!("Minting NFT..."); + let uris = uris + .into_iter() + .map(ManagedBuffer::from) + .collect::>>(); + self.interactor .tx() .from(&self.wallet_address) .to(&self.wallet_address) .gas(100_000_000u64) .typed(UserBuiltinProxy) - .esdt_nft_create( - token_id, - amount, - name, - royalties, - hash, - &NftDummyAttributes { - creation_epoch: 2104, - cool_factor: 5, - }, - &ManagedVec::new(), - ) - .prepare_async() + .esdt_nft_create(token_id, amount, name, royalties, hash, attributes, &uris) + .returns(ReturnsResult) .run() - .await; + .await } - async fn unset_roles( + pub async fn unset_roles( &mut self, address: &Bech32Address, token_id: &[u8], @@ -699,12 +681,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .unset_special_roles(address, token_id, roles.into_iter()) - .prepare_async() .run() .await; } - async fn transfer_ownership(&mut self, token_id: &[u8], new_owner: &Bech32Address) { + pub async fn transfer_ownership(&mut self, token_id: &[u8], new_owner: &Bech32Address) { println!("Transferring token ownership..."); self.interactor @@ -714,12 +695,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .transfer_ownership(token_id, new_owner) - .prepare_async() .run() .await; } - async fn transfer_nft_create_role( + pub async fn transfer_nft_create_role( &mut self, token_id: &[u8], old_owner: &Bech32Address, @@ -734,12 +714,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .transfer_nft_create_role(token_id, old_owner, new_owner) - .prepare_async() .run() .await; } - async fn control_changes(&mut self, token_id: &[u8]) { + pub async fn control_changes(&mut self, token_id: &[u8]) { println!("Control changes"); self.interactor @@ -762,7 +741,108 @@ impl SysFuncCallsInteract { can_add_special_roles: Some(true), }, ) - .prepare_async() + .run() + .await; + } + + pub async fn set_token_type(&mut self, token_id: &[u8], token_type: EsdtTokenType) { + println!("Setting token type to {token_type:?} for token {token_id:?}..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.wallet_address) + .gas(100_000_000u64) + .typed(UserBuiltinProxy) + .esdt_set_token_type(token_id, token_type) + .run() + .await; + } + + pub async fn modify_royalties(&mut self, token_id: &[u8], nonce: u64, new_royalty: u64) { + println!("Modifying royalties for token {token_id:?} into {new_royalty:?}..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.wallet_address) + .gas(100_000_000u64) + .typed(UserBuiltinProxy) + .esdt_modify_royalties(token_id, nonce, new_royalty) + .run() + .await; + } + + pub async fn set_new_uris(&mut self, token_id: &[u8], nonce: u64, new_uris: Vec) { + println!("Setting new uris for token {token_id:?} with nonce {nonce:?}..."); + + let uris = new_uris + .into_iter() + .map(ManagedBuffer::from) + .collect::>>(); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.wallet_address) + .gas(100_000_000u64) + .typed(UserBuiltinProxy) + .esdt_nft_set_new_uris(token_id, nonce, &uris) + .run() + .await; + } + + // changes creator into caller + pub async fn modify_creator(&mut self, token_id: &[u8], nonce: u64) { + println!( + "Modifying the creator (into caller) for token {token_id:?} with nonce {nonce:?}..." + ); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.wallet_address) + .gas(100_000_000u64) + .typed(UserBuiltinProxy) + .esdt_nft_modify_creator(token_id, nonce) + .run() + .await; + } + + pub async fn metadata_recreate( + &mut self, + token_id: &[u8], + nonce: u64, + new_attributes: T, + ) { + println!("Recreating the token {token_id:?} with nonce {nonce:?} with new attributes..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.wallet_address) + .gas(100_000_000u64) + .typed(UserBuiltinProxy) + .esdt_metadata_recreate(token_id, nonce, &new_attributes) + .run() + .await; + } + + pub async fn metadata_update( + &mut self, + token_id: &[u8], + nonce: u64, + new_attributes: T, + ) { + println!("Updating the token {token_id:?} with nonce {nonce:?} with new attributes..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.wallet_address) + .gas(100_000_000u64) + .typed(UserBuiltinProxy) + .esdt_metadata_update(token_id, nonce, &new_attributes) .run() .await; } diff --git a/tools/interactor-system-func-calls/src/system_sc_interact_config.rs b/tools/interactor-system-func-calls/src/system_sc_interact_config.rs index c61059d57e..f2a23a0da5 100644 --- a/tools/interactor-system-func-calls/src/system_sc_interact_config.rs +++ b/tools/interactor-system-func-calls/src/system_sc_interact_config.rs @@ -27,13 +27,20 @@ impl Config { toml::from_str(&content).unwrap() } + pub fn chain_simulator_config() -> Self { + Config { + gateway_uri: "http://localhost:8085".to_owned(), + chain_type: ChainType::Simulator, + } + } + // Returns the gateway URI pub fn gateway_uri(&self) -> &str { &self.gateway_uri } // Returns if chain type is chain simulator - pub fn use_chain_simulator(&self) -> bool { + pub fn is_chain_simulator(&self) -> bool { match self.chain_type { ChainType::Real => false, ChainType::Simulator => true, diff --git a/tools/interactor-system-func-calls/src/system_sc_main.rs b/tools/interactor-system-func-calls/src/system_sc_main.rs new file mode 100644 index 0000000000..89a4ca0a28 --- /dev/null +++ b/tools/interactor-system-func-calls/src/system_sc_main.rs @@ -0,0 +1,6 @@ +extern crate system_sc_interact; + +#[tokio::main] +pub async fn main() { + system_sc_interact::system_sc_interact_cli().await; +} diff --git a/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs new file mode 100644 index 0000000000..00db309334 --- /dev/null +++ b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs @@ -0,0 +1,54 @@ +use multiversx_sc_snippets::imports::{EsdtTokenType, RustBigUint}; +use system_sc_interact::{Config, NftDummyAttributes, SysFuncCallsInteract}; + +#[tokio::test] +#[ignore = "fixes needed"] +async fn cs_builtin_func_tokens_test() { + let mut interact = SysFuncCallsInteract::init(Config::chain_simulator_config()).await; + + // issue dynamic NFT + let dynamic_nft_token_id = interact + .issue_token( + RustBigUint::from(50000000000000000u64), + b"TESTNFT", + b"TEST", + 0usize, + EsdtTokenType::DynamicNFT, + ) + .await; + + println!("Dynamic NFT token id issued: {dynamic_nft_token_id:?}"); + + // mint NFT + let nonce = interact + .mint_nft( + dynamic_nft_token_id.as_bytes(), + RustBigUint::from(1u64), + b"myNFT", + 30u64, + b"", + &NftDummyAttributes { + creation_epoch: 2u64, + cool_factor: 3u8, + }, + Vec::new(), + ) + .await; + + println!("Dynamic NFT minted at nonce {nonce:?}"); + + // modify royalties + interact + .modify_royalties(dynamic_nft_token_id.as_bytes(), nonce, 20u64) + .await; + + println!("Royalties changed for {dynamic_nft_token_id:?} with nonce {nonce:?}"); + + // set new uris + let uris = vec!["thisianuri.com".to_string()]; + interact + .set_new_uris(dynamic_nft_token_id.as_bytes(), nonce, uris) + .await; + + println!("New uris set for {dynamic_nft_token_id:?} with nonce {nonce:?}"); +} From afab864db5a78553793220961d2b2c9d2dbce790 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 3 Dec 2024 03:09:54 +0200 Subject: [PATCH 060/133] ManagedVecItem - ref for EsdtTokenPayment --- chain/core/src/types/flags/esdt_token_type.rs | 2 +- contracts/core/wegld-swap/src/wegld.rs | 8 ++-- .../digital-cash/src/pay_fee_and_fund.rs | 4 +- .../src/esdt_transfer_with_fee.rs | 4 +- .../fractional-nfts/src/fractional_nfts.rs | 2 +- .../examples/nft-subscription/src/lib.rs | 38 ++++++++++++---- .../order-book/pair/src/validation.rs | 14 ++++-- .../seed-nft-minter/src/seed_nft_minter.rs | 2 +- .../src/storage_mapper_fungible_token.rs | 9 ++-- .../first-contract/src/lib.rs | 12 +++--- .../child/src/lib.rs | 2 +- .../src/fwd_call_transf_exec_legacy.rs | 2 +- .../forwarder-legacy/src/fwd_esdt_legacy.rs | 4 +- .../forwarder-raw/src/forwarder_raw.rs | 4 +- .../forwarder-raw/src/forwarder_raw_async.rs | 4 +- .../composability/forwarder/src/fwd_esdt.rs | 4 +- .../src/fwd_call_promises_bt.rs | 14 +++--- .../composability/vault/src/vault.rs | 4 +- .../payable-features/src/payable_features.rs | 10 ++--- .../rust-testing-framework-tester/src/lib.rs | 4 +- .../use-module/src/token_merge_mod_impl.rs | 2 +- .../bonding_curve/utils/owner_endpoints.rs | 19 ++++---- .../src/bonding_curve/utils/user_endpoints.rs | 17 +++++--- .../modules/src/default_issue_callbacks.rs | 2 +- contracts/modules/src/governance/mod.rs | 2 +- contracts/modules/src/token_merge/mod.rs | 2 +- .../wrappers/call_value_wrapper.rs | 43 +++++++++++++------ .../contract_call_convert.rs | 2 +- .../contract_call_exec.rs | 2 +- .../result_handlers/returns_bt_single_esdt.rs | 3 +- .../managed/wrapped/esdt_token_payment.rs | 7 ++- .../scenario/tx_to_step/tx_to_step_call.rs | 2 +- .../tx_to_step/tx_to_step_transfer.rs | 2 +- 33 files changed, 152 insertions(+), 100 deletions(-) diff --git a/chain/core/src/types/flags/esdt_token_type.rs b/chain/core/src/types/flags/esdt_token_type.rs index 74db07c9a6..3668ca6fe6 100644 --- a/chain/core/src/types/flags/esdt_token_type.rs +++ b/chain/core/src/types/flags/esdt_token_type.rs @@ -13,7 +13,7 @@ const ESDT_TYPE_INVALID: &[u8] = &[]; // Note: In the current implementation, SemiFungible is never returned -#[derive(TopDecode, TopEncode, NestedDecode, NestedEncode, Clone, PartialEq, Eq, Debug)] +#[derive(TopDecode, TopEncode, NestedDecode, NestedEncode, Clone, Copy, PartialEq, Eq, Debug)] pub enum EsdtTokenType { Fungible, NonFungible, diff --git a/contracts/core/wegld-swap/src/wegld.rs b/contracts/core/wegld-swap/src/wegld.rs index 23a4493494..1c9cf11a2a 100644 --- a/contracts/core/wegld-swap/src/wegld.rs +++ b/contracts/core/wegld-swap/src/wegld.rs @@ -39,10 +39,10 @@ pub trait EgldEsdtSwap: multiversx_sc_modules::pause::PauseModule { let (payment_token, payment_amount) = self.call_value().single_fungible_esdt(); let wrapped_egld_token_id = self.wrapped_egld_token_id().get(); - require!(payment_token == wrapped_egld_token_id, "Wrong esdt token"); - require!(payment_amount > 0u32, "Must pay more than 0 tokens!"); + require!(*payment_token == wrapped_egld_token_id, "Wrong esdt token"); + require!(*payment_amount > 0u32, "Must pay more than 0 tokens!"); require!( - payment_amount <= self.get_locked_egld_balance(), + *payment_amount <= self.get_locked_egld_balance(), "Contract does not have enough funds" ); @@ -51,7 +51,7 @@ pub trait EgldEsdtSwap: multiversx_sc_modules::pause::PauseModule { // 1 wrapped eGLD = 1 eGLD, so we pay back the same amount let caller = self.blockchain().get_caller(); - self.tx().to(&caller).egld(&payment_amount).transfer(); + self.tx().to(&caller).egld(&*payment_amount).transfer(); } #[view(getLockedEgldBalance)] diff --git a/contracts/examples/digital-cash/src/pay_fee_and_fund.rs b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs index 45e913c51d..edff9df18e 100644 --- a/contracts/examples/digital-cash/src/pay_fee_and_fund.rs +++ b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs @@ -7,8 +7,8 @@ pub trait PayFeeAndFund: storage::StorageModule + helpers::HelpersModule { #[endpoint(payFeeAndFundESDT)] #[payable("*")] fn pay_fee_and_fund_esdt(&self, address: ManagedAddress, valability: u64) { - let mut payments = self.call_value().all_esdt_transfers().clone_value(); - let fee = EgldOrEsdtTokenPayment::from(payments.get(0)); + let mut payments = self.call_value().all_esdt_transfers().clone(); + let fee = EgldOrEsdtTokenPayment::from(payments.get(0).clone()); let caller_address = self.blockchain().get_caller(); self.update_fees(caller_address, &address, fee); diff --git a/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs b/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs index de883ef83a..5967c8feaa 100644 --- a/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs +++ b/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs @@ -71,13 +71,13 @@ pub trait EsdtTransferWithFee { "Mismatching payment for covering fees" ); let _ = self.get_payment_after_fees(fee_type, &next_payment); - new_payments.push(payment); + new_payments.push(payment.clone()); }, Fee::Percentage(_) => { new_payments.push(self.get_payment_after_fees(fee_type, &payment)); }, Fee::Unset => { - new_payments.push(payment); + new_payments.push(payment.clone()); }, } } diff --git a/contracts/examples/fractional-nfts/src/fractional_nfts.rs b/contracts/examples/fractional-nfts/src/fractional_nfts.rs index 16f1c87aed..2b9844449a 100644 --- a/contracts/examples/fractional-nfts/src/fractional_nfts.rs +++ b/contracts/examples/fractional-nfts/src/fractional_nfts.rs @@ -74,7 +74,7 @@ pub trait FractionalNfts: default_issue_callbacks::DefaultIssueCallbacksModule { let fractional_token = fractional_token_mapper.get_token_id_ref(); let hash = ManagedBuffer::new(); let fractional_info = - FractionalUriInfo::new(original_payment, initial_fractional_amount.clone()); + FractionalUriInfo::new(original_payment.clone(), initial_fractional_amount.clone()); let uris = fractional_info.to_uris(); let fractional_nonce = self.send().esdt_nft_create( diff --git a/contracts/examples/nft-subscription/src/lib.rs b/contracts/examples/nft-subscription/src/lib.rs index 7b0b63096e..210a20020f 100644 --- a/contracts/examples/nft-subscription/src/lib.rs +++ b/contracts/examples/nft-subscription/src/lib.rs @@ -49,34 +49,54 @@ pub trait NftSubscription: #[payable("*")] #[endpoint] fn update_attributes(&self, attributes: ManagedBuffer) { - let (id, nonce, _) = self.call_value().single_esdt().into_tuple(); - self.update_subscription_attributes::(&id, nonce, attributes); + let payment = self.call_value().single_esdt(); + self.update_subscription_attributes::( + &payment.token_identifier, + payment.token_nonce, + attributes, + ); self.tx() .to(ToCaller) - .single_esdt(&id, nonce, &BigUint::from(1u8)) + .single_esdt( + &payment.token_identifier, + payment.token_nonce, + &BigUint::from(1u8), + ) .transfer(); } #[payable("*")] #[endpoint] fn renew(&self, duration: u64) { - let (id, nonce, _) = self.call_value().single_esdt().into_tuple(); - self.renew_subscription::(&id, nonce, duration); + let payment = self.call_value().single_esdt(); + self.renew_subscription::( + &payment.token_identifier, + payment.token_nonce, + duration, + ); self.tx() .to(ToCaller) - .single_esdt(&id, nonce, &BigUint::from(1u8)) + .single_esdt( + &payment.token_identifier, + payment.token_nonce, + &BigUint::from(1u8), + ) .transfer(); } #[payable("*")] #[endpoint] fn cancel(&self) { - let (id, nonce, _) = self.call_value().single_esdt().into_tuple(); - self.cancel_subscription::(&id, nonce); + let payment = self.call_value().single_esdt(); + self.cancel_subscription::(&payment.token_identifier, payment.token_nonce); self.tx() .to(ToCaller) - .single_esdt(&id, nonce, &BigUint::from(1u8)) + .single_esdt( + &payment.token_identifier, + payment.token_nonce, + &BigUint::from(1u8), + ) .transfer(); } diff --git a/contracts/examples/order-book/pair/src/validation.rs b/contracts/examples/order-book/pair/src/validation.rs index 488edbdb24..306f299014 100644 --- a/contracts/examples/order-book/pair/src/validation.rs +++ b/contracts/examples/order-book/pair/src/validation.rs @@ -72,22 +72,28 @@ pub trait ValidationModule: common::CommonModule { let (token_id, amount) = self.call_value().single_fungible_esdt(); let second_token_id = self.second_token_id().get(); require!( - token_id == second_token_id, + *token_id == second_token_id, "Token in and second token id should be the same" ); - Payment { token_id, amount } + Payment { + token_id: token_id.clone(), + amount: amount.clone(), + } } fn require_valid_sell_payment(&self) -> Payment { let (token_id, amount) = self.call_value().single_fungible_esdt(); let first_token_id = self.first_token_id().get(); require!( - token_id == first_token_id, + *token_id == first_token_id, "Token in and first token id should be the same" ); - Payment { token_id, amount } + Payment { + token_id: token_id.clone(), + amount: amount.clone(), + } } fn require_valid_match_input_order_ids(&self, order_ids: &ManagedVec) { diff --git a/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs b/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs index 510212891b..98734c0fb0 100644 --- a/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs +++ b/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs @@ -102,7 +102,7 @@ pub trait SeedNftMinter: } else { esdt_payments .try_get(0) - .map(|esdt_payment| esdt_payment.amount) + .map(|esdt_payment| esdt_payment.amount.clone()) .unwrap_or_default() }; total_amount += amount; diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs b/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs index 6eccdd3f83..feeecb2b33 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs @@ -61,8 +61,9 @@ pub trait FungibleTokenMapperFeatures: fn custom_issue_non_zero_supply_cb(&self, #[call_result] result: ManagedAsyncCallResult<()>) { match result { ManagedAsyncCallResult::Ok(()) => { - let token_identifier = self.call_value().single_esdt().token_identifier; - self.fungible_token_mapper().set_token_id(token_identifier); + let token_identifier = &self.call_value().single_esdt().token_identifier; + self.fungible_token_mapper() + .set_token_id(token_identifier.clone()); }, ManagedAsyncCallResult::Err(_) => { self.fungible_token_mapper().clear(); @@ -128,9 +129,9 @@ pub trait FungibleTokenMapperFeatures: #[payable("*")] #[endpoint] fn require_same_token_fungible(&self) { - let payment_token = self.call_value().single_esdt().token_identifier; + let payment_token = &self.call_value().single_esdt().token_identifier; self.fungible_token_mapper() - .require_same_token(&payment_token); + .require_same_token(payment_token); } #[payable("*")] diff --git a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs index bf77e7ab4e..f4d09b555e 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs +++ b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs @@ -25,7 +25,7 @@ pub trait FirstContract { let expected_token_identifier = self.get_contract_esdt_token_identifier(); require!( - actual_token_identifier == expected_token_identifier, + *actual_token_identifier == expected_token_identifier, "Wrong esdt token" ); @@ -45,13 +45,13 @@ pub trait FirstContract { let expected_token_identifier = self.get_contract_esdt_token_identifier(); require!( - actual_token_identifier == expected_token_identifier, + *actual_token_identifier == expected_token_identifier, "Wrong esdt token" ); self.call_esdt_second_contract( &expected_token_identifier, - &(esdt_value / 2u32), + &(esdt_value.clone() / 2u32), &self.get_second_contract_address(), &ManagedBuffer::from(SECOND_CONTRACT_ACCEPT_ESDT_PAYMENT), &ManagedVec::new(), @@ -65,7 +65,7 @@ pub trait FirstContract { let expected_token_identifier = self.get_contract_esdt_token_identifier(); require!( - actual_token_identifier == expected_token_identifier, + *actual_token_identifier == expected_token_identifier, "Wrong esdt token" ); @@ -86,7 +86,7 @@ pub trait FirstContract { let expected_token_identifier = self.get_contract_esdt_token_identifier(); require!( - actual_token_identifier == expected_token_identifier, + *actual_token_identifier == expected_token_identifier, "Wrong esdt token" ); @@ -107,7 +107,7 @@ pub trait FirstContract { let expected_token_identifier = self.get_contract_esdt_token_identifier(); require!( - actual_token_identifier == expected_token_identifier, + *actual_token_identifier == expected_token_identifier, "Wrong esdt token" ); diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs index e763a222af..dcb634f054 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs @@ -46,7 +46,7 @@ pub trait Child { #[callback] fn esdt_issue_callback(&self, #[call_result] _result: IgnoreValue) { let (token_identifier, _amount) = self.call_value().single_fungible_esdt(); - self.wrapped_egld_token_identifier().set(&token_identifier); + self.wrapped_egld_token_identifier().set(token_identifier); } // storage diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_transf_exec_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_transf_exec_legacy.rs index e789e4644f..645f173b28 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_transf_exec_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_transf_exec_legacy.rs @@ -28,7 +28,7 @@ pub trait ForwarderTransferExecuteModule { self.vault_proxy() .contract(to) .accept_funds() - .payment((payment.token_identifier, 0, payment.amount)) + .single_esdt(&payment.token_identifier, 0, &payment.amount) .transfer_execute(); } diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs index 6fa20793d8..7ba477b448 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs @@ -39,8 +39,8 @@ pub trait ForwarderEsdtModule: fwd_storage_legacy::ForwarderStorageModule { #[endpoint] fn send_esdt_with_fees(&self, to: ManagedAddress, percentage_fees: BigUint) { let (token_id, payment) = self.call_value().single_fungible_esdt(); - let fees = &payment * &percentage_fees / PERCENTAGE_TOTAL; - let amount_to_send = payment - fees; + let fees = &*payment * &percentage_fees / PERCENTAGE_TOTAL; + let amount_to_send = payment.clone() - fees; self.send().direct_esdt(&to, &token_id, 0, &amount_to_send); } diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs index a436e97b7a..796bea5684 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs @@ -37,9 +37,9 @@ pub trait ForwarderRaw: } else { for payment in payments.iter() { let _ = self.callback_payments().push(&( - EgldOrEsdtTokenIdentifier::esdt(payment.token_identifier), + EgldOrEsdtTokenIdentifier::esdt(payment.token_identifier.clone()), payment.token_nonce, - payment.amount, + payment.amount.clone(), )); } } 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 47240f3c52..df66f30a30 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 @@ -114,8 +114,8 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { let (token, payment) = self.call_value().single_fungible_esdt(); self.forward_contract_call( to, - EgldOrEsdtTokenIdentifier::esdt(token), - payment, + EgldOrEsdtTokenIdentifier::esdt(token.clone()), + payment.clone(), endpoint_name, args, ) diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs b/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs index a4dbaa28b1..425ca07053 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs @@ -42,8 +42,8 @@ pub trait ForwarderEsdtModule: fwd_storage::ForwarderStorageModule { #[endpoint] fn send_esdt_with_fees(&self, to: ManagedAddress, percentage_fees: BigUint) { let (token_id, payment) = self.call_value().single_fungible_esdt(); - let fees = &payment * &percentage_fees / PERCENTAGE_TOTAL; - let amount_to_send = payment - fees; + let fees = percentage_fees * &*payment / PERCENTAGE_TOTAL; + let amount_to_send = payment.clone() - fees; self.tx() .to(&to) diff --git a/contracts/feature-tests/composability/promises-features/src/fwd_call_promises_bt.rs b/contracts/feature-tests/composability/promises-features/src/fwd_call_promises_bt.rs index 2634e2c5ac..ba73843958 100644 --- a/contracts/feature-tests/composability/promises-features/src/fwd_call_promises_bt.rs +++ b/contracts/feature-tests/composability/promises-features/src/fwd_call_promises_bt.rs @@ -45,15 +45,19 @@ pub trait CallPromisesBackTransfersModule: common::CommonModule { } for esdt_transfer in &back_transfers.esdt_payments { - let (token, nonce, payment) = esdt_transfer.into_tuple(); - let esdt_token_id = EgldOrEsdtTokenIdentifier::esdt(token); - self.retrieve_funds_callback_event(&esdt_token_id, nonce, &payment); + let esdt_token_id = + EgldOrEsdtTokenIdentifier::esdt(esdt_transfer.token_identifier.clone()); + self.retrieve_funds_callback_event( + &esdt_token_id, + esdt_transfer.token_nonce, + &esdt_transfer.amount, + ); let _ = self.callback_data().push(&CallbackData { callback_name: ManagedBuffer::from(b"retrieve_funds_callback"), token_identifier: esdt_token_id, - token_nonce: nonce, - token_amount: payment, + token_nonce: esdt_transfer.token_nonce, + token_amount: esdt_transfer.amount.clone(), args: ManagedVec::new(), }); } diff --git a/contracts/feature-tests/composability/vault/src/vault.rs b/contracts/feature-tests/composability/vault/src/vault.rs index 37b0d65b9e..d6f3feb81b 100644 --- a/contracts/feature-tests/composability/vault/src/vault.rs +++ b/contracts/feature-tests/composability/vault/src/vault.rs @@ -240,9 +240,9 @@ pub trait Vault { ); new_tokens.push(EsdtTokenPayment::new( - payment.token_identifier, + payment.token_identifier.clone(), new_token_nonce, - payment.amount, + payment.amount.clone(), )); } diff --git a/contracts/feature-tests/payable-features/src/payable_features.rs b/contracts/feature-tests/payable-features/src/payable_features.rs index d8296f8592..6cad32b135 100644 --- a/contracts/feature-tests/payable-features/src/payable_features.rs +++ b/contracts/feature-tests/payable-features/src/payable_features.rs @@ -35,7 +35,7 @@ pub trait PayableFeatures { #[payable("*")] fn payment_array_3(&self) -> MultiValue3 { let [payment_a, payment_b, payment_c] = self.call_value().multi_esdt(); - (payment_a, payment_b, payment_c).into() + (payment_a.clone(), payment_b.clone(), payment_c.clone()).into() } #[endpoint] @@ -129,7 +129,7 @@ pub trait PayableFeatures { &self, #[payment] payment: BigUint, ) -> MultiValue2 { - let token = self.call_value().single_esdt().token_identifier; + let token = self.call_value().single_esdt().token_identifier.clone(); (payment, token).into() } @@ -140,14 +140,14 @@ pub trait PayableFeatures { #[payment_token] token: EgldOrEsdtTokenIdentifier, ) -> MultiValue2 { let payment = self.call_value().single_esdt(); - (payment.amount, token).into() + (payment.amount.clone(), token).into() } #[endpoint] #[payable("PAYABLE-FEATURES-TOKEN")] fn payable_token_4(&self) -> MultiValue2 { - let payment = self.call_value().single_esdt().amount; - let token = self.call_value().single_esdt().token_identifier; + let payment = self.call_value().single_esdt().amount.clone(); + let token = self.call_value().single_esdt().token_identifier.clone(); (payment, token).into() } } diff --git a/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs b/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs index ffc411dad0..9d7be05858 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs @@ -71,7 +71,7 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[endpoint] fn receive_esdt(&self) -> (TokenIdentifier, BigUint) { let payment = self.call_value().single_esdt(); - (payment.token_identifier, payment.amount) + (payment.token_identifier.clone(), payment.amount.clone()) } #[payable("*")] @@ -84,7 +84,7 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[endpoint] fn receive_esdt_half(&self) { let payment = self.call_value().single_esdt(); - let amount = payment.amount / 2u32; + let amount = &payment.amount / 2u32; self.tx() .to(ToCaller) diff --git a/contracts/feature-tests/use-module/src/token_merge_mod_impl.rs b/contracts/feature-tests/use-module/src/token_merge_mod_impl.rs index b5d7711481..04f7b9cc7d 100644 --- a/contracts/feature-tests/use-module/src/token_merge_mod_impl.rs +++ b/contracts/feature-tests/use-module/src/token_merge_mod_impl.rs @@ -55,7 +55,7 @@ pub trait TokenMergeModImpl: ) -> ManagedVec { let payment = self.call_value().single_esdt(); let attributes_creator = DefaultMergedAttributesWrapper::new(); - self.split_token_partial(payment, tokens_to_remove, &attributes_creator) + self.split_token_partial(payment.clone(), tokens_to_remove, &attributes_creator) } } diff --git a/contracts/modules/src/bonding_curve/utils/owner_endpoints.rs b/contracts/modules/src/bonding_curve/utils/owner_endpoints.rs index 382e1fbc28..1c51d47905 100644 --- a/contracts/modules/src/bonding_curve/utils/owner_endpoints.rs +++ b/contracts/modules/src/bonding_curve/utils/owner_endpoints.rs @@ -90,11 +90,14 @@ pub trait OwnerEndpointsModule: storage::StorageModule + events::EventsModule { + PartialEq + Default, { - let (identifier, nonce, amount) = self.call_value().single_esdt().into_tuple(); + let esdt_payment = self.call_value().single_esdt(); + let identifier = &esdt_payment.token_identifier; + let nonce = esdt_payment.token_nonce; + let amount = &esdt_payment.amount; let caller = self.blockchain().get_caller(); let mut set_payment = EgldOrEsdtTokenIdentifier::egld(); - if self.bonding_curve(&identifier).is_empty() { + if self.bonding_curve(identifier).is_empty() { match payment_token { OptionalValue::Some(token) => set_payment = EgldOrEsdtTokenIdentifier::esdt(token), OptionalValue::None => { @@ -102,27 +105,27 @@ pub trait OwnerEndpointsModule: storage::StorageModule + events::EventsModule { }, }; } - if self.token_details(&identifier).is_empty() { + if self.token_details(identifier).is_empty() { let nonces = ManagedVec::from_single_item(nonce); - self.token_details(&identifier).set(&TokenOwnershipData { + self.token_details(identifier).set(&TokenOwnershipData { token_nonces: nonces, owner: caller.clone(), }); } else { - let mut details = self.token_details(&identifier).get(); + let mut details = self.token_details(identifier).get(); require!( details.owner == caller, "The token was already deposited by another address" ); if !details.token_nonces.contains(&nonce) { details.token_nonces.push(nonce); - self.token_details(&identifier).set(&details); + self.token_details(identifier).set(&details); } } - self.set_curve_storage::(&identifier, amount.clone(), set_payment); + self.set_curve_storage::(identifier, amount.clone(), set_payment); self.owned_tokens(&caller).insert(identifier.clone()); - self.nonce_amount(&identifier, nonce) + self.nonce_amount(identifier, nonce) .update(|current_amount| *current_amount += amount); } diff --git a/contracts/modules/src/bonding_curve/utils/user_endpoints.rs b/contracts/modules/src/bonding_curve/utils/user_endpoints.rs index f627d26256..a51236512a 100644 --- a/contracts/modules/src/bonding_curve/utils/user_endpoints.rs +++ b/contracts/modules/src/bonding_curve/utils/user_endpoints.rs @@ -21,11 +21,14 @@ pub trait UserEndpointsModule: storage::StorageModule + events::EventsModule { + PartialEq + Default, { - let (offered_token, nonce, sell_amount) = self.call_value().single_esdt().into_tuple(); - let _ = self.check_owned_return_payment_token::(&offered_token, &sell_amount); + let esdt_payment = self.call_value().single_esdt(); + let offered_token = &esdt_payment.token_identifier; + let nonce = esdt_payment.token_nonce; + let sell_amount = &esdt_payment.amount; + let _ = self.check_owned_return_payment_token::(offered_token, sell_amount); let (calculated_price, payment_token) = - self.bonding_curve(&offered_token).update(|buffer| { + self.bonding_curve(offered_token).update(|buffer| { let serializer = ManagedSerializer::new(); let mut bonding_curve: BondingCurve = @@ -35,9 +38,9 @@ pub trait UserEndpointsModule: storage::StorageModule + events::EventsModule { bonding_curve.sell_availability, "Selling is not available on this token" ); - let price = self.compute_sell_price::(&offered_token, &sell_amount); + let price = self.compute_sell_price::(offered_token, sell_amount); bonding_curve.payment.amount -= &price; - bonding_curve.arguments.balance += &sell_amount; + bonding_curve.arguments.balance += sell_amount; let payment_token = bonding_curve.payment_token(); *buffer = serializer.top_encode_to_managed_buffer(&bonding_curve); (price, payment_token) @@ -45,7 +48,7 @@ pub trait UserEndpointsModule: storage::StorageModule + events::EventsModule { let caller = self.blockchain().get_caller(); - self.nonce_amount(&offered_token, nonce) + self.nonce_amount(offered_token, nonce) .update(|val| *val += sell_amount); self.tx() @@ -53,7 +56,7 @@ pub trait UserEndpointsModule: storage::StorageModule + events::EventsModule { .egld_or_single_esdt(&payment_token, 0u64, &calculated_price) .transfer(); - self.token_details(&offered_token) + self.token_details(offered_token) .update(|details| details.add_nonce(nonce)); self.sell_token_event(&caller, &calculated_price); diff --git a/contracts/modules/src/default_issue_callbacks.rs b/contracts/modules/src/default_issue_callbacks.rs index 6edd7abeec..8e9e1c6e90 100644 --- a/contracts/modules/src/default_issue_callbacks.rs +++ b/contracts/modules/src/default_issue_callbacks.rs @@ -35,7 +35,7 @@ pub trait DefaultIssueCallbacksModule { let key = StorageKey::from(storage_key); match result { ManagedAsyncCallResult::Ok(()) => { - let token_id = self.call_value().single_esdt().token_identifier; + let token_id = self.call_value().single_esdt().token_identifier.clone(); storage_set(key.as_ref(), &TokenMapperState::Token(token_id)); }, ManagedAsyncCallResult::Err(_) => { diff --git a/contracts/modules/src/governance/mod.rs b/contracts/modules/src/governance/mod.rs index 85dfa4e1b4..4d407cf593 100644 --- a/contracts/modules/src/governance/mod.rs +++ b/contracts/modules/src/governance/mod.rs @@ -435,7 +435,7 @@ pub trait GovernanceModule: payment.token_identifier == self.governance_token_id().get(), "Only Governance token accepted as payment" ); - payment + payment.clone() } fn require_valid_proposal_id(&self, proposal_id: usize) { diff --git a/contracts/modules/src/token_merge/mod.rs b/contracts/modules/src/token_merge/mod.rs index b940980dfe..dad6665c0d 100644 --- a/contracts/modules/src/token_merge/mod.rs +++ b/contracts/modules/src/token_merge/mod.rs @@ -69,7 +69,7 @@ pub trait TokenMergeModule: } for single_token_instance in single_tokens { - all_merged_instances.add_or_update_instance(single_token_instance); + all_merged_instances.add_or_update_instance(single_token_instance.clone()); } let merged_token_payment = diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 3006805ef0..3fb85e1658 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -8,8 +8,8 @@ use crate::{ err_msg, types::{ BigUint, ConstDecimals, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, - EgldOrMultiEsdtPayment, EsdtTokenPayment, ManagedDecimal, ManagedRef, ManagedVec, - TokenIdentifier, + EgldOrMultiEsdtPayment, EsdtTokenPayment, ManagedDecimal, ManagedRef, ManagedType, + ManagedVec, ManagedVecRef, TokenIdentifier, }, }; @@ -71,12 +71,12 @@ where /// Can be used to extract all payments in one line like this: /// /// `let [payment_a, payment_b, payment_c] = self.call_value().multi_esdt();`. - pub fn multi_esdt(&self) -> [EsdtTokenPayment; N] { - self.all_esdt_transfers() - .to_array_of_refs::() - .unwrap_or_else(|| { - A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_ESDT_TRANSFERS.as_bytes()) - }) + pub fn multi_esdt(&self) -> [ManagedVecRef<'static, EsdtTokenPayment>; N] { + let esdt_transfers = self.all_esdt_transfers(); + let array = esdt_transfers.to_array_of_refs::().unwrap_or_else(|| { + A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_ESDT_TRANSFERS.as_bytes()) + }); + unsafe { core::mem::transmute(array) } } /// Expects precisely one ESDT token transfer, fungible or not. @@ -84,9 +84,13 @@ where /// Will return the received ESDT payment. /// /// The amount cannot be 0, since that would not qualify as an ESDT transfer. - pub fn single_esdt(&self) -> EsdtTokenPayment { - let [payments] = self.multi_esdt(); - payments + pub fn single_esdt(&self) -> ManagedVecRef<'static, EsdtTokenPayment> { + let esdt_transfers = self.all_esdt_transfers(); + if esdt_transfers.len() != 1 { + A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_ESDT_TRANSFERS.as_bytes()) + } + let value = esdt_transfers.get(0); + unsafe { core::mem::transmute(value) } } /// Expects precisely one fungible ESDT token transfer. @@ -94,12 +98,23 @@ where /// Returns the token ID and the amount for fungible ESDT transfers. /// /// The amount cannot be 0, since that would not qualify as an ESDT transfer. - pub fn single_fungible_esdt(&self) -> (TokenIdentifier, BigUint) { + pub fn single_fungible_esdt( + &self, + ) -> ( + ManagedRef<'static, A, TokenIdentifier>, + ManagedRef<'static, A, BigUint>, + ) { let payment = self.single_esdt(); if payment.token_nonce != 0 { A::error_api_impl().signal_error(err_msg::FUNGIBLE_TOKEN_EXPECTED_ERR_MSG.as_bytes()); } - (payment.token_identifier, payment.amount) + + unsafe { + ( + ManagedRef::wrap_handle(payment.token_identifier.get_handle()), + ManagedRef::wrap_handle(payment.amount.get_handle()), + ) + } } /// Accepts and returns either an EGLD payment, or a single ESDT token. @@ -115,7 +130,7 @@ where token_nonce: 0, amount: self.egld_value().clone_value(), }, - 1 => esdt_transfers.get(0).into(), + 1 => esdt_transfers.get(0).clone().into(), _ => A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_ESDT_TRANSFERS.as_bytes()), } } diff --git a/framework/base/src/types/interaction/contract_call_legacy/contract_call_convert.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_convert.rs index fe4225d9a4..6a66c3e0f5 100644 --- a/framework/base/src/types/interaction/contract_call_legacy/contract_call_convert.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_convert.rs @@ -20,7 +20,7 @@ where ) -> Self { match payments.len() { 0 => self, - 1 => self.convert_to_single_transfer_esdt_call(payments.get(0)), + 1 => self.convert_to_single_transfer_esdt_call(payments.get(0).clone()), _ => self.convert_to_multi_transfer_esdt_call(payments), } } diff --git a/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs index f0f1722f24..e2281a4b38 100644 --- a/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs @@ -208,7 +208,7 @@ where pub(super) fn transfer_execute_esdt(self, payments: ManagedVec>) { match payments.len() { 0 => self.transfer_execute_egld(BigUint::zero()), - 1 => self.transfer_execute_single_esdt(payments.get(0)), + 1 => self.transfer_execute_single_esdt(payments.get(0).clone()), _ => self.transfer_execute_multi_esdt(payments), } } diff --git a/framework/base/src/types/interaction/result_handlers/returns_bt_single_esdt.rs b/framework/base/src/types/interaction/result_handlers/returns_bt_single_esdt.rs index 996891c1c2..10a4c59003 100644 --- a/framework/base/src/types/interaction/result_handlers/returns_bt_single_esdt.rs +++ b/framework/base/src/types/interaction/result_handlers/returns_bt_single_esdt.rs @@ -28,6 +28,7 @@ where Env::Api::error_api_impl().signal_error(b"Back transfers expected to be a single ESDT") } - esdt_payments.get(0) + let x = esdt_payments.get(0).clone(); + x } } diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index b676fa42cc..041ddd1f64 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -15,7 +15,7 @@ use crate::{ use super::{ managed_vec_item_read_from_payload_index, managed_vec_item_save_to_payload_index, ManagedVec, - ManagedVecItemPayloadBuffer, + ManagedVecItemPayloadBuffer, ManagedVecRef, }; #[type_abi] @@ -168,7 +168,7 @@ impl IntoMultiValue for EsdtTokenPayment { impl ManagedVecItem for EsdtTokenPayment { type PAYLOAD = ManagedVecItemPayloadBuffer<16>; const SKIPS_RESERIALIZATION: bool = false; - type Ref<'a> = Self; + type Ref<'a> = ManagedVecRef<'a, Self>; fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; @@ -182,8 +182,7 @@ impl ManagedVecItem for EsdtTokenPayment { } unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { - // TODO: managed ref - Self::read_from_payload(payload) + ManagedVecRef::new(Self::read_from_payload(payload)) } fn save_to_payload(self, payload: &mut Self::PAYLOAD) { diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs index 0661806509..752437a130 100644 --- a/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs @@ -71,7 +71,7 @@ where step.tx.esdt_value = full_payment_data .multi_esdt .iter() - .map(TxESDT::from) + .map(|item| TxESDT::from(item.clone())) .collect(); } diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs index d2baa6bc6c..782f86dc16 100644 --- a/framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs @@ -52,7 +52,7 @@ where step.tx.esdt_value = full_payment_data .multi_esdt .iter() - .map(TxESDT::from) + .map(|item| TxESDT::from(item.clone())) .collect(); } From e5b7db922d860db604cb46a7e254ec0d789d92e3 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Tue, 3 Dec 2024 17:38:33 +0100 Subject: [PATCH 061/133] bugfixing, interactor testing, new issue dynamic function, small interactor decode fix --- .../contract_base/wrappers/send_wrapper.rs | 16 +++- .../system_proxy/builtin_func_proxy.rs | 28 ++++++- .../system_proxy/esdt_system_sc_proxy.rs | 69 ++++++++++++++-- .../system_proxy/legacy_system_sc_proxy.rs | 49 ++++++++++- framework/snippets/src/network_response.rs | 5 ++ .../src/system_sc_interact.rs | 65 +++++++++++++-- .../tests/chain_simulator_token_tests.rs | 82 ++++++++++++++++++- 7 files changed, 287 insertions(+), 27 deletions(-) diff --git a/framework/base/src/contract_base/wrappers/send_wrapper.rs b/framework/base/src/contract_base/wrappers/send_wrapper.rs index 468d75c92c..09809956bb 100644 --- a/framework/base/src/contract_base/wrappers/send_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/send_wrapper.rs @@ -817,32 +817,42 @@ where } /// Recreates an ESDT token with the newly specified attributes. + #[allow(clippy::too_many_arguments)] pub fn esdt_metadata_recreate( &self, token_id: TokenIdentifier, nonce: u64, + name: ManagedBuffer, + royalties: u64, + hash: ManagedBuffer, new_attributes: &T, + uris: ManagedVec>, ) { Tx::new_tx_from_sc() .to(ToSelf) .gas(GasLeft) .typed(system_proxy::UserBuiltinProxy) - .esdt_metadata_recreate(token_id, nonce, new_attributes) + .esdt_metadata_recreate(token_id, nonce, name, royalties, hash, new_attributes, uris) .sync_call() } /// Updates an ESDT token with the newly specified attributes. + #[allow(clippy::too_many_arguments)] pub fn esdt_metadata_update( &self, - token_id: &TokenIdentifier, + token_id: TokenIdentifier, nonce: u64, + name: ManagedBuffer, + royalties: u64, + hash: ManagedBuffer, new_attributes: &T, + uris: ManagedVec>, ) { Tx::new_tx_from_sc() .to(ToSelf) .gas(GasLeft) .typed(system_proxy::UserBuiltinProxy) - .esdt_metadata_update(token_id, nonce, new_attributes) + .esdt_metadata_update(token_id, nonce, name, royalties, hash, new_attributes, uris) .sync_call() } } diff --git a/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs b/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs index 1612965f4b..8388332d75 100644 --- a/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs @@ -301,15 +301,23 @@ where tx.original_result() } + #[allow(clippy::too_many_arguments)] pub fn esdt_metadata_recreate< T: TopEncode, Arg0: ProxyArg>, Arg1: ProxyArg, + Arg2: ProxyArg>, + Arg3: ProxyArg, + Arg4: ProxyArg>, >( self, token_id: Arg0, nonce: Arg1, + name: Arg2, + royalties: Arg3, + hash: Arg4, new_attributes: &T, + uris: ManagedVec>, ) -> TxTypedCall { let tx = self .wrapped_tx @@ -317,20 +325,32 @@ where .raw_call(ESDT_METADATA_RECREATE_FUNC_NAME) .argument(&token_id) .argument(&nonce) - .argument(&new_attributes); + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&new_attributes) + .argument(&uris); tx.original_result() } + #[allow(clippy::too_many_arguments)] pub fn esdt_metadata_update< T: TopEncode, Arg0: ProxyArg>, Arg1: ProxyArg, + Arg2: ProxyArg>, + Arg3: ProxyArg, + Arg4: ProxyArg>, >( self, token_id: Arg0, nonce: Arg1, + name: Arg2, + royalties: Arg3, + hash: Arg4, new_attributes: &T, + uris: ManagedVec>, ) -> TxTypedCall { let tx = self .wrapped_tx @@ -338,7 +358,11 @@ where .raw_call(ESDT_METADATA_UPDATE_FUNC_NAME) .argument(&token_id) .argument(&nonce) - .argument(&new_attributes); + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&new_attributes) + .argument(&uris); tx.original_result() } diff --git a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs index ccea8494d3..e2f74ded4e 100644 --- a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs @@ -231,14 +231,70 @@ where EsdtTokenType::Invalid => "", }; - self.wrapped_tx + let mut tx = self + .wrapped_tx .raw_call(endpoint) .egld(issue_cost) .argument(&token_display_name) .argument(&token_ticker) - .argument(&token_type_name) - .argument(&num_decimals) - .original_result() + .argument(&token_type_name); + + if token_type_name == "META" { + tx = tx.argument(&num_decimals); + } else { + assert!( + num_decimals == 0usize, + "only META tokens accept number of decimals > 0" + ); + } + + tx.original_result() + } + + /// Issues dynamic ESDT tokens + pub fn issue_dynamic< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + issue_cost: BigUint, + token_display_name: Arg0, + token_ticker: Arg1, + token_type: EsdtTokenType, + num_decimals: usize, + ) -> IssueCall { + let endpoint_name = match token_type { + EsdtTokenType::DynamicNFT | EsdtTokenType::DynamicSFT | EsdtTokenType::DynamicMeta => { + REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME + }, + _ => "", + }; + + let token_type_name = match token_type { + EsdtTokenType::DynamicNFT => "NFT", + EsdtTokenType::DynamicSFT => "SFT", + EsdtTokenType::DynamicMeta => "META", + _ => "", + }; + + let mut tx = self + .wrapped_tx + .raw_call(endpoint_name) + .egld(issue_cost) + .argument(&token_display_name) + .argument(&token_ticker) + .argument(&token_type_name); + + if token_type_name == "META" { + tx = tx.argument(&num_decimals); + } else { + assert!( + num_decimals == 0usize, + "only META tokens accept number of decimals > 0" + ); + } + + tx.original_result() } /// Deduplicates code from all the possible issue functions @@ -260,10 +316,7 @@ where EsdtTokenType::NonFungible => ISSUE_NON_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::SemiFungible => ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::Meta => REGISTER_META_ESDT_ENDPOINT_NAME, - EsdtTokenType::DynamicNFT | EsdtTokenType::DynamicSFT | EsdtTokenType::DynamicMeta => { - REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME - }, - EsdtTokenType::Invalid => "", + _ => "", }; let mut tx = self diff --git a/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs index a7cdeb4570..cbc06fb3b1 100644 --- a/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs @@ -213,6 +213,50 @@ where .argument(&num_decimals) } + /// Issues dynamic ESDT tokens + pub fn issue_dynamic( + self, + issue_cost: BigUint, + token_display_name: &ManagedBuffer, + token_ticker: &ManagedBuffer, + token_type: EsdtTokenType, + num_decimals: usize, + ) -> ContractCallWithEgld { + let esdt_system_sc_address = self.esdt_system_sc_address(); + + let endpoint_name = match token_type { + EsdtTokenType::DynamicNFT | EsdtTokenType::DynamicSFT | EsdtTokenType::DynamicMeta => { + REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME + }, + _ => "", + }; + + let token_type_name = match token_type { + EsdtTokenType::DynamicNFT => "NFT", + EsdtTokenType::DynamicSFT => "SFT", + EsdtTokenType::DynamicMeta => "META", + _ => "", + }; + + let mut contract_call = + ContractCallWithEgld::new(esdt_system_sc_address, endpoint_name, issue_cost); + + contract_call.proxy_arg(token_display_name); + contract_call.proxy_arg(token_ticker); + contract_call.proxy_arg(&token_type_name); + + if token_type_name == "META" { + contract_call.proxy_arg(&num_decimals); + } else { + assert!( + num_decimals == 0usize, + "only META tokens accept number of decimals > 0" + ); + } + + contract_call + } + /// Deduplicates code from all the possible issue functions fn issue( self, @@ -230,10 +274,7 @@ where EsdtTokenType::NonFungible => ISSUE_NON_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::SemiFungible => ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME, EsdtTokenType::Meta => REGISTER_META_ESDT_ENDPOINT_NAME, - EsdtTokenType::DynamicNFT | EsdtTokenType::DynamicSFT | EsdtTokenType::DynamicMeta => { - REGISTER_DYNAMIC_ESDT_ENDPOINT_NAME - }, - EsdtTokenType::Invalid => "", + _ => "", }; let mut contract_call = diff --git a/framework/snippets/src/network_response.rs b/framework/snippets/src/network_response.rs index c17ae4456d..3e6bb2931d 100644 --- a/framework/snippets/src/network_response.rs +++ b/framework/snippets/src/network_response.rs @@ -173,12 +173,17 @@ fn process_new_issued_token_identifier(tx: &TransactionOnNetwork) -> Option { basic_interact - .issue_token( + .issue_token_all_roles( args.cost.clone(), args.display_name.as_bytes(), args.ticker.as_bytes(), @@ -360,7 +360,40 @@ impl SysFuncCallsInteract { println!("SFT Collection ID: {:?}", sft_collection_id); } - pub async fn issue_token( + pub async fn issue_dynamic_token( + &mut self, + issue_cost: RustBigUint, + token_display_name: &[u8], + token_ticker: &[u8], + token_type: EsdtTokenType, + num_decimals: usize, + ) -> String { + println!("Registering dynamic token {token_ticker:?} of type {token_type:?}..."); + + let token_id = self + .interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .issue_dynamic( + issue_cost.into(), + token_display_name, + token_ticker, + token_type, + num_decimals, + ) + .returns(ReturnsNewTokenIdentifier) + .run() + .await; + + println!("TOKEN ID: {:?}", token_id); + + token_id + } + + pub async fn issue_token_all_roles( &mut self, issue_cost: RustBigUint, token_display_name: &[u8], @@ -809,40 +842,60 @@ impl SysFuncCallsInteract { .await; } + #[allow(clippy::too_many_arguments)] pub async fn metadata_recreate( &mut self, token_id: &[u8], nonce: u64, - new_attributes: T, + name: &[u8], + royalties: u64, + hash: &[u8], + new_attributes: &T, + uris: Vec, ) { println!("Recreating the token {token_id:?} with nonce {nonce:?} with new attributes..."); + let uris = uris + .into_iter() + .map(ManagedBuffer::from) + .collect::>>(); + self.interactor .tx() .from(&self.wallet_address) .to(&self.wallet_address) .gas(100_000_000u64) .typed(UserBuiltinProxy) - .esdt_metadata_recreate(token_id, nonce, &new_attributes) + .esdt_metadata_recreate(token_id, nonce, name, royalties, hash, new_attributes, uris) .run() .await; } + #[allow(clippy::too_many_arguments)] pub async fn metadata_update( &mut self, token_id: &[u8], nonce: u64, - new_attributes: T, + name: &[u8], + royalties: u64, + hash: &[u8], + new_attributes: &T, + uris: Vec, ) { println!("Updating the token {token_id:?} with nonce {nonce:?} with new attributes..."); + let uris = uris + .into_iter() + .map(ManagedBuffer::from) + .collect::>>(); + self.interactor .tx() .from(&self.wallet_address) .to(&self.wallet_address) .gas(100_000_000u64) .typed(UserBuiltinProxy) - .esdt_metadata_update(token_id, nonce, &new_attributes) + .esdt_metadata_update(token_id, nonce, name, royalties, hash, new_attributes, uris) .run() .await; } diff --git a/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs index 00db309334..a789ed9a92 100644 --- a/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs +++ b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs @@ -1,15 +1,53 @@ use multiversx_sc_snippets::imports::{EsdtTokenType, RustBigUint}; use system_sc_interact::{Config, NftDummyAttributes, SysFuncCallsInteract}; +const ISSUE_COST: u64 = 50000000000000000u64; + +// real blockchain tests for now, fixes needed for chain simulator #[tokio::test] -#[ignore = "fixes needed"] +#[ignore = "run on demand"] async fn cs_builtin_func_tokens_test() { - let mut interact = SysFuncCallsInteract::init(Config::chain_simulator_config()).await; + // let mut interact = SysFuncCallsInteract::init(Config::chain_simulator_config()).await; + + let mut interact = SysFuncCallsInteract::init(Config::load_config()).await; // issue dynamic NFT + interact + .issue_dynamic_token( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + EsdtTokenType::DynamicNFT, + 0usize, + ) + .await; + + // issue dynamic SFT + interact + .issue_dynamic_token( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + EsdtTokenType::DynamicSFT, + 0usize, + ) + .await; + + // issue dynamic META + interact + .issue_dynamic_token( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + EsdtTokenType::DynamicMeta, + 18usize, + ) + .await; + + // issue dynamic NFT with all roles let dynamic_nft_token_id = interact - .issue_token( - RustBigUint::from(50000000000000000u64), + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), b"TESTNFT", b"TEST", 0usize, @@ -51,4 +89,40 @@ async fn cs_builtin_func_tokens_test() { .await; println!("New uris set for {dynamic_nft_token_id:?} with nonce {nonce:?}"); + + // metadata update + interact + .metadata_update( + dynamic_nft_token_id.as_bytes(), + nonce, + b"TESTNFT", + 30u64, + b"new_hash", + &NftDummyAttributes { + creation_epoch: 3u64, + cool_factor: 5u8, + }, + Vec::new(), + ) + .await; + + println!("Metadata updated for {dynamic_nft_token_id:?} with nonce {nonce:?}"); + + // metadata recreate + interact + .metadata_recreate( + dynamic_nft_token_id.as_bytes(), + nonce, + b"TESTNFT", + 30u64, + b"new_hash_recreated", + &NftDummyAttributes { + creation_epoch: 100u64, + cool_factor: 1u8, + }, + Vec::new(), + ) + .await; + + println!("Metadata recreated for {dynamic_nft_token_id:?} with nonce {nonce:?}. A new token has been created."); } From 4b8e7d05fee296c32cc25b9e49889c576b54e682 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Tue, 3 Dec 2024 19:18:23 +0100 Subject: [PATCH 062/133] change to dynamic impl, bugfixes, more tests --- .../system_proxy/esdt_system_sc_proxy.rs | 27 ++++---- .../system_proxy/legacy_system_sc_proxy.rs | 23 ++++--- .../src/system_sc_interact.rs | 14 ++++ .../tests/chain_simulator_token_tests.rs | 67 +++++++++++++++++++ 4 files changed, 108 insertions(+), 23 deletions(-) diff --git a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs index e2f74ded4e..468243d024 100644 --- a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs @@ -239,13 +239,8 @@ where .argument(&token_ticker) .argument(&token_type_name); - if token_type_name == "META" { + if token_type != EsdtTokenType::DynamicNFT && token_type != EsdtTokenType::DynamicSFT { tx = tx.argument(&num_decimals); - } else { - assert!( - num_decimals == 0usize, - "only META tokens accept number of decimals > 0" - ); } tx.original_result() @@ -285,13 +280,8 @@ where .argument(&token_ticker) .argument(&token_type_name); - if token_type_name == "META" { + if token_type != EsdtTokenType::DynamicNFT && token_type != EsdtTokenType::DynamicSFT { tx = tx.argument(&num_decimals); - } else { - assert!( - num_decimals == 0usize, - "only META tokens accept number of decimals > 0" - ); } tx.original_result() @@ -649,6 +639,19 @@ where append_token_property_arguments(&mut tx.data, property_arguments); tx.original_result() } + + /// Changes token to dynamic. + /// Does not work for: FungibleESDT, NonFungibleESDT, NonFungibleESDTv2. + pub fn change_to_dynamic>>( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("changeToDynamic") + .argument(&token_id) + .original_result() + } } const TRUE_STR: &str = "true"; diff --git a/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs index cbc06fb3b1..3f5d9aaccb 100644 --- a/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs @@ -206,11 +206,17 @@ where EsdtTokenType::Invalid => "", }; - ContractCallWithEgld::new(esdt_system_sc_address, endpoint, issue_cost) - .argument(&token_display_name) - .argument(&token_ticker) - .argument(&token_type_name) - .argument(&num_decimals) + let mut contract_call = + ContractCallWithEgld::new(esdt_system_sc_address, endpoint, issue_cost) + .argument(&token_display_name) + .argument(&token_ticker) + .argument(&token_type_name); + + if token_type != EsdtTokenType::DynamicNFT { + contract_call = contract_call.argument(&num_decimals); + } + + contract_call } /// Issues dynamic ESDT tokens @@ -245,13 +251,8 @@ where contract_call.proxy_arg(token_ticker); contract_call.proxy_arg(&token_type_name); - if token_type_name == "META" { + if token_type != EsdtTokenType::DynamicNFT { contract_call.proxy_arg(&num_decimals); - } else { - assert!( - num_decimals == 0usize, - "only META tokens accept number of decimals > 0" - ); } contract_call diff --git a/tools/interactor-system-func-calls/src/system_sc_interact.rs b/tools/interactor-system-func-calls/src/system_sc_interact.rs index f29f82fa17..f98acaea98 100644 --- a/tools/interactor-system-func-calls/src/system_sc_interact.rs +++ b/tools/interactor-system-func-calls/src/system_sc_interact.rs @@ -445,6 +445,20 @@ impl SysFuncCallsInteract { .await; } + pub async fn change_to_dynamic(&mut self, token_id: &[u8]) { + println!("Changing the following token {token_id:?} to dynamic..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .change_to_dynamic(TokenIdentifier::from(token_id)) + .run() + .await; + } + pub async fn mint_sft( &mut self, token_id: &[u8], diff --git a/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs index a789ed9a92..57cb67dccd 100644 --- a/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs +++ b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs @@ -44,6 +44,28 @@ async fn cs_builtin_func_tokens_test() { ) .await; + // issue dynamic META with all roles + let _ = interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 0usize, + EsdtTokenType::DynamicMeta, + ) + .await; + + // issue dynamic SFT with all roles + let _ = interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 0usize, + EsdtTokenType::DynamicSFT, + ) + .await; + // issue dynamic NFT with all roles let dynamic_nft_token_id = interact .issue_token_all_roles( @@ -126,3 +148,48 @@ async fn cs_builtin_func_tokens_test() { println!("Metadata recreated for {dynamic_nft_token_id:?} with nonce {nonce:?}. A new token has been created."); } + +#[tokio::test] +#[ignore = "run on demand"] +async fn change_to_dynamic_test() { + let mut interact = SysFuncCallsInteract::init(Config::load_config()).await; + + // issue NFT with all roles + let _ = interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 0usize, + EsdtTokenType::NonFungible, + ) + .await; + + // issue META token with all roles + let meta_token_id = interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 18usize, + EsdtTokenType::Meta, + ) + .await; + + // change META to dynamic + interact.change_to_dynamic(meta_token_id.as_bytes()).await; + + // issue SFT token with all roles + let sft_token_id = interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 18usize, + EsdtTokenType::SemiFungible, + ) + .await; + + // change SFT to dynamic + interact.change_to_dynamic(sft_token_id.as_bytes()).await; +} From 98ef758fc65d3989a1fc601633eba0eb65be36c9 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 4 Dec 2024 14:45:20 +0200 Subject: [PATCH 063/133] ManagedVec iter - file rename --- framework/base/src/types/managed/wrapped.rs | 8 ++++---- ...anaged_vec_owned_iter.rs => managed_vec_iter_owned.rs} | 0 .../{managed_vec_ref_iter.rs => managed_vec_iter_ref.rs} | 0 3 files changed, 4 insertions(+), 4 deletions(-) rename framework/base/src/types/managed/wrapped/{managed_vec_owned_iter.rs => managed_vec_iter_owned.rs} (100%) rename framework/base/src/types/managed/wrapped/{managed_vec_ref_iter.rs => managed_vec_iter_ref.rs} (100%) diff --git a/framework/base/src/types/managed/wrapped.rs b/framework/base/src/types/managed/wrapped.rs index 088a250d5d..3924b7b3da 100644 --- a/framework/base/src/types/managed/wrapped.rs +++ b/framework/base/src/types/managed/wrapped.rs @@ -19,9 +19,9 @@ mod managed_vec; mod managed_vec_item; mod managed_vec_item_nested_tuple; mod managed_vec_item_payload; -mod managed_vec_owned_iter; +mod managed_vec_iter_owned; +mod managed_vec_iter_ref; mod managed_vec_ref; -mod managed_vec_ref_iter; mod managed_vec_ref_mut; pub(crate) mod preloaded_managed_buffer; mod randomness_source; @@ -53,9 +53,9 @@ pub use managed_vec_item::{ }; pub use managed_vec_item_nested_tuple::ManagedVecItemNestedTuple; pub use managed_vec_item_payload::*; -pub use managed_vec_owned_iter::ManagedVecOwnedIterator; +pub use managed_vec_iter_owned::ManagedVecOwnedIterator; +pub use managed_vec_iter_ref::ManagedVecRefIterator; pub use managed_vec_ref::ManagedVecRef; -pub use managed_vec_ref_iter::ManagedVecRefIterator; pub use managed_vec_ref_mut::ManagedVecRefMut; pub use randomness_source::RandomnessSource; pub use token_identifier::TokenIdentifier; diff --git a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs similarity index 100% rename from framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs rename to framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs diff --git a/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs similarity index 100% rename from framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs rename to framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs From 1db87bb2a3616b7c2a92fde6bde7f4ed7c35da9c Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 4 Dec 2024 15:09:14 +0200 Subject: [PATCH 064/133] Cargo.lock update --- Cargo.lock | 178 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee094a3520..6eb7455172 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,9 +160,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "anymap2" @@ -262,6 +262,7 @@ dependencies = [ "clap", "multiversx-sc-snippets", "serde", + "serial_test", "tokio", "toml", ] @@ -413,15 +414,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cc" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" dependencies = [ "shlex", ] @@ -485,9 +486,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.21" +version = "4.5.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" +checksum = "69371e34337c4c984bbe322360c2547210bf632eb2814bbe78a6e87a2935bd2b" dependencies = [ "clap_builder", "clap_derive", @@ -495,9 +496,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.21" +version = "4.5.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" +checksum = "6e24c1b4099818523236a8ca881d2b45db98dadfb4625cf6608c12069fcbbde1" dependencies = [ "anstream", "anstyle", @@ -1014,12 +1015,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1515,7 +1516,7 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils 0.2.0", - "http 1.1.0", + "http 1.2.0", "js-sys", "pin-project", "serde", @@ -1617,8 +1618,8 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.1.0", - "indexmap 2.6.0", + "http 1.2.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -1708,9 +1709,9 @@ dependencies = [ [[package]] name = "http" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -1724,7 +1725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http 1.2.0", ] [[package]] @@ -1735,7 +1736,7 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body", "pin-project-lite", ] @@ -1762,7 +1763,7 @@ dependencies = [ "futures-channel", "futures-util", "h2", - "http 1.1.0", + "http 1.2.0", "http-body", "httparse", "itoa", @@ -1779,7 +1780,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http 1.1.0", + "http 1.2.0", "hyper", "hyper-util", "rustls", @@ -1815,7 +1816,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body", "hyper", "pin-project-lite", @@ -2001,9 +2002,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -2060,10 +2061,11 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -2169,9 +2171,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.166" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "linked-list-repeat" @@ -2330,11 +2332,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi", "libc", "wasi", "windows-sys 0.52.0", @@ -3445,7 +3446,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 1.1.0", + "http 1.2.0", "http-body", "http-body-util", "hyper", @@ -3580,9 +3581,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustc_version" @@ -3676,6 +3677,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scc" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b202022bb57c049555430e11fc22fea12909276a80a4c3d368da36ac1d88ed" +dependencies = [ + "sdd", +] + [[package]] name = "scenario-tester" version = "0.0.0" @@ -3719,6 +3729,12 @@ dependencies = [ "sha2", ] +[[package]] +name = "sdd" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49c1eeaf4b6a87c7479688c6d52b9f1153cedd3c489300564f932b065c6eab95" + [[package]] name = "second-contract" version = "0.0.0" @@ -3835,7 +3851,7 @@ version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "memchr", "ryu", @@ -3874,6 +3890,31 @@ dependencies = [ "serde", ] +[[package]] +name = "serial_test" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" +dependencies = [ + "futures", + "log", + "once_cell", + "parking_lot", + "scc", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "set-repeat" version = "0.0.0" @@ -4193,9 +4234,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.41.1" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -4254,9 +4295,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -4271,7 +4312,7 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", @@ -4293,7 +4334,7 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", @@ -4534,9 +4575,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" dependencies = [ "cfg-if", "once_cell", @@ -4545,9 +4586,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" dependencies = [ "bumpalo", "log", @@ -4560,21 +4601,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4582,9 +4624,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" dependencies = [ "proc-macro2", "quote", @@ -4595,18 +4637,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" [[package]] name = "wasm-encoder" -version = "0.221.0" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de35b6c3ef1f53ac7a31b5e69bc00f1542ea337e7e7162dc34c68b537ff82690" +checksum = "c17a3bd88f2155da63a1f2fcb8a56377a24f0b6dfed12733bb5f544e86f690c5" dependencies = [ "leb128", - "wasmparser 0.221.0", + "wasmparser 0.221.2", ] [[package]] @@ -4618,19 +4660,19 @@ dependencies = [ "ahash", "bitflags", "hashbrown 0.14.5", - "indexmap 2.6.0", + "indexmap 2.7.0", "semver", "serde", ] [[package]] name = "wasmparser" -version = "0.221.0" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8659e755615170cfe20da468865c989da78c5da16d8652e69a75acda02406a92" +checksum = "9845c470a2e10b61dd42c385839cdd6496363ed63b5c9e420b5488b77bd22083" dependencies = [ "bitflags", - "indexmap 2.6.0", + "indexmap 2.7.0", "semver", ] @@ -4647,9 +4689,9 @@ dependencies = [ [[package]] name = "wast" -version = "221.0.0" +version = "221.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d8eb1933d493dd07484a255c3f52236123333f5befaa3be36182a50d393ec54" +checksum = "fcc4470b9de917ba199157d1f0ae104f2ae362be728c43e68c571c7715bd629e" dependencies = [ "bumpalo", "leb128", @@ -4660,18 +4702,18 @@ dependencies = [ [[package]] name = "wat" -version = "1.221.0" +version = "1.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c813fd4e5b2b97242830b56e7b7dc5479bc17aaa8730109be35e61909af83993" +checksum = "6b1f3c6d82af47286494c6caea1d332037f5cbeeac82bbf5ef59cb8c201c466e" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" dependencies = [ "js-sys", "wasm-bindgen", @@ -5077,7 +5119,7 @@ dependencies = [ "crossbeam-utils", "displaydoc", "flate2", - "indexmap 2.6.0", + "indexmap 2.7.0", "memchr", "thiserror", "zopfli", From 0df3c0a42f3f22e4f2975768adaca5c5699e8456 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 4 Dec 2024 15:21:54 +0200 Subject: [PATCH 065/133] ManagedVec iterator refactor, ManagedVecPayloadIterator --- framework/base/src/types/managed/wrapped.rs | 2 + .../managed/wrapped/managed_vec_iter_owned.rs | 62 ++--------- .../wrapped/managed_vec_iter_payload.rs | 103 ++++++++++++++++++ .../managed/wrapped/managed_vec_iter_ref.rs | 58 ++++------ 4 files changed, 134 insertions(+), 91 deletions(-) create mode 100644 framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs diff --git a/framework/base/src/types/managed/wrapped.rs b/framework/base/src/types/managed/wrapped.rs index 3924b7b3da..52d827c79f 100644 --- a/framework/base/src/types/managed/wrapped.rs +++ b/framework/base/src/types/managed/wrapped.rs @@ -20,6 +20,7 @@ mod managed_vec_item; mod managed_vec_item_nested_tuple; mod managed_vec_item_payload; mod managed_vec_iter_owned; +mod managed_vec_iter_payload; mod managed_vec_iter_ref; mod managed_vec_ref; mod managed_vec_ref_mut; @@ -54,6 +55,7 @@ pub use managed_vec_item::{ pub use managed_vec_item_nested_tuple::ManagedVecItemNestedTuple; pub use managed_vec_item_payload::*; pub use managed_vec_iter_owned::ManagedVecOwnedIterator; +pub use managed_vec_iter_payload::ManagedVecPayloadIterator; pub use managed_vec_iter_ref::ManagedVecRefIterator; pub use managed_vec_ref::ManagedVecRef; pub use managed_vec_ref_mut::ManagedVecRefMut; diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs index b688bb466c..055b4b4a11 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs @@ -1,6 +1,6 @@ -use crate::api::ManagedTypeApi; +use crate::{api::ManagedTypeApi, types::ManagedType}; -use super::{ManagedVec, ManagedVecItem, ManagedVecItemPayload}; +use super::{ManagedVec, ManagedVecItem, ManagedVecPayloadIterator}; impl IntoIterator for ManagedVec where @@ -19,9 +19,7 @@ where M: ManagedTypeApi, T: ManagedVecItem, { - managed_vec: ManagedVec, - byte_start: usize, - byte_end: usize, + payload_iter: ManagedVecPayloadIterator, } impl ManagedVecOwnedIterator @@ -30,11 +28,10 @@ where T: ManagedVecItem, { pub(crate) fn new(managed_vec: ManagedVec) -> Self { - let byte_end = managed_vec.byte_len(); - ManagedVecOwnedIterator { - managed_vec, - byte_start: 0, - byte_end, + unsafe { + ManagedVecOwnedIterator { + payload_iter: ManagedVecPayloadIterator::new(managed_vec.forget_into_handle()), + } } } } @@ -47,26 +44,12 @@ where type Item = T; fn next(&mut self) -> Option { - // managedrev / reference type - let next_byte_start = self.byte_start + T::payload_size(); - if next_byte_start > self.byte_end { - return None; - } - - let mut payload = T::PAYLOAD::new_buffer(); - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_start, payload.payload_slice_mut()); - - self.byte_start = next_byte_start; + let payload = self.payload_iter.next()?; Some(T::read_from_payload(&payload)) } fn size_hint(&self) -> (usize, Option) { - let size = T::payload_size(); - let remaining = (self.byte_end - self.byte_start) / size; - (remaining, Some(remaining)) + self.payload_iter.size_hint() } } @@ -83,32 +66,7 @@ where T: ManagedVecItem, { fn next_back(&mut self) -> Option { - if self.byte_start + T::payload_size() > self.byte_end { - return None; - } - self.byte_end -= T::payload_size(); - - let mut payload = T::PAYLOAD::new_buffer(); - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_end, payload.payload_slice_mut()); - + let payload = self.payload_iter.next_back()?; Some(T::read_from_payload(&payload)) } } - -impl Clone for ManagedVecOwnedIterator -where - M: ManagedTypeApi, - T: ManagedVecItem + Clone, -{ - fn clone(&self) -> Self { - let byte_end = self.byte_end; - Self { - managed_vec: self.managed_vec.clone(), - byte_start: self.byte_start, - byte_end, - } - } -} diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs new file mode 100644 index 0000000000..44293133d2 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs @@ -0,0 +1,103 @@ +use core::marker::PhantomData; + +use crate::api::{ManagedBufferApiImpl, ManagedTypeApi}; + +use super::ManagedVecItemPayload; + +pub struct ManagedVecPayloadIterator +where + M: ManagedTypeApi, + P: ManagedVecItemPayload, +{ + pub(super) vec_handle: M::ManagedBufferHandle, + byte_start: usize, + byte_end: usize, + _phantom: PhantomData

, +} + +impl ManagedVecPayloadIterator +where + M: ManagedTypeApi, + P: ManagedVecItemPayload, +{ + /// Unsafe because it works with the managed vec handle directly, so does not take ownership into account. + pub(crate) unsafe fn new(vec_handle: M::ManagedBufferHandle) -> Self { + let byte_end = M::managed_type_impl().mb_len(vec_handle.clone()); + ManagedVecPayloadIterator { + vec_handle, + byte_start: 0, + byte_end, + _phantom: PhantomData, + } + } + + /// Unsafe because it works with the managed vec handle directly, so does not take ownership into account. + pub(super) unsafe fn clone_iter(&self) -> Self { + ManagedVecPayloadIterator { + vec_handle: self.vec_handle.clone(), + byte_start: self.byte_start, + byte_end: self.byte_end, + _phantom: PhantomData, + } + } +} + +impl Iterator for ManagedVecPayloadIterator +where + M: ManagedTypeApi, + P: ManagedVecItemPayload, +{ + type Item = P; + + fn next(&mut self) -> Option

{ + let next_byte_start = self.byte_start + P::payload_size(); + if next_byte_start > self.byte_end { + return None; + } + + let mut payload = P::new_buffer(); + let _ = M::managed_type_impl().mb_load_slice( + self.vec_handle.clone(), + self.byte_start, + payload.payload_slice_mut(), + ); + + self.byte_start = next_byte_start; + Some(payload) + } + + fn size_hint(&self) -> (usize, Option) { + let size = P::payload_size(); + let remaining = (self.byte_end - self.byte_start) / size; + (remaining, Some(remaining)) + } +} + +impl ExactSizeIterator for ManagedVecPayloadIterator +where + M: ManagedTypeApi, + P: ManagedVecItemPayload, +{ +} + +impl DoubleEndedIterator for ManagedVecPayloadIterator +where + M: ManagedTypeApi, + P: ManagedVecItemPayload, +{ + fn next_back(&mut self) -> Option { + if self.byte_start + P::payload_size() > self.byte_end { + return None; + } + self.byte_end -= P::payload_size(); + + let mut payload = P::new_buffer(); + let _ = M::managed_type_impl().mb_load_slice( + self.vec_handle.clone(), + self.byte_end, + payload.payload_slice_mut(), + ); + + Some(payload) + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs index c0c0f89485..b57a16d3d7 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs @@ -1,6 +1,8 @@ -use crate::api::ManagedTypeApi; +use core::marker::PhantomData; -use super::{ManagedVec, ManagedVecItem, ManagedVecItemPayload}; +use crate::{api::ManagedTypeApi, types::ManagedType}; + +use super::{ManagedVec, ManagedVecItem, ManagedVecPayloadIterator}; impl<'a, M, T> IntoIterator for &'a ManagedVec where @@ -19,9 +21,8 @@ where M: ManagedTypeApi, T: ManagedVecItem, { - managed_vec: &'a ManagedVec, - byte_start: usize, - byte_end: usize, + payload_iter: ManagedVecPayloadIterator, + _phantom: PhantomData<&'a ManagedVec>, } impl<'a, M, T> ManagedVecRefIterator<'a, M, T> @@ -30,10 +31,11 @@ where T: ManagedVecItem, { pub(crate) fn new(managed_vec: &'a ManagedVec) -> Self { - ManagedVecRefIterator { - managed_vec, - byte_start: 0, - byte_end: managed_vec.byte_len(), + unsafe { + ManagedVecRefIterator { + payload_iter: ManagedVecPayloadIterator::new(managed_vec.get_handle()), + _phantom: PhantomData, + } } } } @@ -46,25 +48,12 @@ where type Item = T::Ref<'a>; fn next(&mut self) -> Option { - let next_byte_start = self.byte_start + T::payload_size(); - if next_byte_start > self.byte_end { - return None; - } - - let mut payload = T::PAYLOAD::new_buffer(); - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_start, payload.payload_slice_mut()); - - self.byte_start = next_byte_start; - + let payload = self.payload_iter.next()?; unsafe { Some(T::borrow_from_payload(&payload)) } } fn size_hint(&self) -> (usize, Option) { - let remaining = (self.byte_end - self.byte_start) / T::payload_size(); - (remaining, Some(remaining)) + self.payload_iter.size_hint() } } @@ -81,17 +70,7 @@ where T: ManagedVecItem, { fn next_back(&mut self) -> Option { - if self.byte_start + T::payload_size() > self.byte_end { - return None; - } - self.byte_end -= T::payload_size(); - - let mut payload = T::PAYLOAD::new_buffer(); - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_end, payload.payload_slice_mut()); - + let payload = self.payload_iter.next_back()?; unsafe { Some(T::borrow_from_payload(&payload)) } } } @@ -102,10 +81,11 @@ where T: ManagedVecItem, { fn clone(&self) -> Self { - Self { - managed_vec: self.managed_vec, - byte_start: self.byte_start, - byte_end: self.byte_end, + unsafe { + ManagedVecRefIterator { + payload_iter: self.payload_iter.clone_iter(), + _phantom: PhantomData, + } } } } From e8dfee4c76c06c30f02182c64f1ec0e3d069bdb9 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Wed, 4 Dec 2024 14:41:23 +0100 Subject: [PATCH 066/133] update token endpoint, tests --- .../system_proxy/esdt_system_sc_proxy.rs | 12 +++++++++++ .../src/system_sc_interact.rs | 14 +++++++++++++ .../tests/chain_simulator_token_tests.rs | 20 +++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs index 468243d024..7e4e0fb4ed 100644 --- a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs @@ -652,6 +652,18 @@ where .argument(&token_id) .original_result() } + + /// Updates a specific token to the newest version. + pub fn update_token>>( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("updateTokenID") + .argument(&token_id) + .original_result() + } } const TRUE_STR: &str = "true"; diff --git a/tools/interactor-system-func-calls/src/system_sc_interact.rs b/tools/interactor-system-func-calls/src/system_sc_interact.rs index f98acaea98..28ecc05034 100644 --- a/tools/interactor-system-func-calls/src/system_sc_interact.rs +++ b/tools/interactor-system-func-calls/src/system_sc_interact.rs @@ -459,6 +459,20 @@ impl SysFuncCallsInteract { .await; } + pub async fn update_token(&mut self, token_id: &[u8]) { + println!("Updating the following token {token_id:?} to the newest version..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .update_token(TokenIdentifier::from(token_id)) + .run() + .await; + } + pub async fn mint_sft( &mut self, token_id: &[u8], diff --git a/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs index 57cb67dccd..ba0f83c9f7 100644 --- a/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs +++ b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs @@ -193,3 +193,23 @@ async fn change_to_dynamic_test() { // change SFT to dynamic interact.change_to_dynamic(sft_token_id.as_bytes()).await; } + +#[tokio::test] +#[ignore = "run on demand"] +async fn update_token_test() { + let mut interact = SysFuncCallsInteract::init(Config::load_config()).await; + + // issue NFT with all roles + let nft_token_id = interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 0usize, + EsdtTokenType::NonFungible, + ) + .await; + + // update NFT + interact.update_token(nft_token_id.as_bytes()).await; +} From 90820a022410906a0b8c72147a31df4607fc71fc Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 5 Dec 2024 05:41:39 +0200 Subject: [PATCH 067/133] clippy cleanup --- framework/base/src/types/managed/basic/managed_buffer.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index d3c0c28e38..01f26277c8 100644 --- a/framework/base/src/types/managed/basic/managed_buffer.rs +++ b/framework/base/src/types/managed/basic/managed_buffer.rs @@ -406,14 +406,13 @@ impl PartialEq for ManagedBuffer { impl Eq for ManagedBuffer {} impl PartialEq<&[u8; N]> for ManagedBuffer { - #[allow(clippy::op_ref)] // clippy is wrong here, it is not needless fn eq(&self, other: &&[u8; N]) -> bool { if self.len() != N { return false; } let mut self_bytes = [0u8; N]; let _ = M::managed_type_impl().mb_load_slice(self.handle.clone(), 0, &mut self_bytes[..]); - &self_bytes[..] == &other[..] + self_bytes[..] == other[..] } } From 0f19b6ae41897d082860700b9d34df8cef67455e Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 5 Dec 2024 07:35:56 +0200 Subject: [PATCH 068/133] call value - EGLD backwards compatibility protection --- .../src/api/managed_types/const_handles.rs | 1 + .../wrappers/call_value_wrapper.rs | 70 ++++++++++++++++--- framework/base/src/err_msg.rs | 1 + .../wrapped/managed_vec_iter_payload.rs | 10 ++- 4 files changed, 70 insertions(+), 12 deletions(-) diff --git a/framework/base/src/api/managed_types/const_handles.rs b/framework/base/src/api/managed_types/const_handles.rs index 283d9c55c6..6d990f9c6e 100644 --- a/framework/base/src/api/managed_types/const_handles.rs +++ b/framework/base/src/api/managed_types/const_handles.rs @@ -22,6 +22,7 @@ pub const CALL_VALUE_SINGLE_ESDT_TOKEN_NAME: RawHandle = -22; pub const CALLBACK_CLOSURE_ARGS_BUFFER: RawHandle = -23; pub const MBUF_TEMPORARY_1: RawHandle = -25; pub const MBUF_TEMPORARY_2: RawHandle = -26; +pub const MBUF_EGLD_000000: RawHandle = -27; pub const ADDRESS_CALLER: RawHandle = -30; pub const ADDRESS_SELF: RawHandle = -31; diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 3fb85e1658..a1f44e026e 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -3,16 +3,19 @@ use core::marker::PhantomData; use crate::{ api::{ const_handles, use_raw_handle, CallValueApi, CallValueApiImpl, ErrorApi, ErrorApiImpl, - HandleConstraints, ManagedTypeApi, StaticVarApiImpl, + HandleConstraints, ManagedBufferApiImpl, ManagedTypeApi, StaticVarApiImpl, }, err_msg, types::{ BigUint, ConstDecimals, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, EsdtTokenPayment, ManagedDecimal, ManagedRef, ManagedType, - ManagedVec, ManagedVecRef, TokenIdentifier, + ManagedVec, ManagedVecItem, ManagedVecItemPayload, ManagedVecPayloadIterator, + ManagedVecRef, TokenIdentifier, }, }; +const EGLD_000000_TOKEN_IDENTIFIER: &str = "EGLD-000000"; + #[derive(Default)] pub struct CallValueWrapper where @@ -55,13 +58,11 @@ where /// Will return 0 results if nothing was transfered, or just EGLD. /// Fully managed underlying types, very efficient. pub fn all_esdt_transfers(&self) -> ManagedRef<'static, A, ManagedVec>> { - let mut call_value_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().get_call_value_multi_esdt_handle()); - if call_value_handle == const_handles::UNINITIALIZED_HANDLE { - call_value_handle = use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT); - A::static_var_api_impl() - .set_call_value_multi_esdt_handle(call_value_handle.get_raw_handle()); - A::call_value_api_impl().load_all_esdt_transfers(call_value_handle.clone()); + let call_value_handle = load_all_transfers::(); + + let egld_payment = find_egld_000000_transfer::(call_value_handle.clone()); + if egld_payment.is_some() { + A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_ESDT_TRANSFERS.as_bytes()) } unsafe { ManagedRef::wrap_handle(call_value_handle) } } @@ -164,3 +165,54 @@ where } } } + +fn load_all_transfers() -> A::ManagedBufferHandle +where + A: CallValueApi + ErrorApi + ManagedTypeApi, +{ + let mut call_value_handle: A::ManagedBufferHandle = + use_raw_handle(A::static_var_api_impl().get_call_value_multi_esdt_handle()); + if call_value_handle == const_handles::UNINITIALIZED_HANDLE { + call_value_handle = use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT); + A::static_var_api_impl() + .set_call_value_multi_esdt_handle(call_value_handle.get_raw_handle()); + A::call_value_api_impl().load_all_esdt_transfers(call_value_handle.clone()); + } + call_value_handle +} + +fn find_egld_000000_transfer( + transfers_vec_handle: A::ManagedBufferHandle, +) -> Option +where + A: CallValueApi + ErrorApi + ManagedTypeApi, +{ + A::managed_type_impl().mb_overwrite( + use_raw_handle(const_handles::MBUF_EGLD_000000), + EGLD_000000_TOKEN_IDENTIFIER.as_bytes(), + ); + unsafe { + let mut iter: ManagedVecPayloadIterator< + A, + as ManagedVecItem>::PAYLOAD, + > = ManagedVecPayloadIterator::new(transfers_vec_handle); + + if iter.remaining_count() <= 1 { + // EGLD is not allowed in single transfers + return None; + } + + let egld_payload = iter.find(|payload| { + let token_identifier_handle = i32::read_from_payload(payload.slice_unchecked(0)); + A::managed_type_impl().mb_eq( + use_raw_handle(const_handles::MBUF_EGLD_000000), + use_raw_handle(token_identifier_handle), + ) + }); + + egld_payload.map(|payload| { + let amount_handle = i32::read_from_payload(payload.slice_unchecked(12)); + use_raw_handle(amount_handle) + }) + } +} diff --git a/framework/base/src/err_msg.rs b/framework/base/src/err_msg.rs index 361775d5f9..5067013c77 100644 --- a/framework/base/src/err_msg.rs +++ b/framework/base/src/err_msg.rs @@ -7,6 +7,7 @@ pub const BAD_TOKEN_TICKER_FORMAT: &str = "bad token ticker format"; pub const SINGLE_ESDT_EXPECTED: &str = "function expects single ESDT payment"; pub const TOO_MANY_ESDT_TRANSFERS: &str = "too many ESDT transfers"; pub const ESDT_INVALID_TOKEN_INDEX: &str = "invalid token index"; +pub const ESDT_UNEXPECTED_EGLD: &str = "unexpected EGLD transfer"; pub const INCORRECT_NUM_ESDT_TRANSFERS: &str = "incorrect number of ESDT transfers"; pub static FUNGIBLE_TOKEN_EXPECTED_ERR_MSG: &str = "fungible ESDT token expected"; diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs index 44293133d2..da8ccddfde 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs @@ -9,7 +9,7 @@ where M: ManagedTypeApi, P: ManagedVecItemPayload, { - pub(super) vec_handle: M::ManagedBufferHandle, + vec_handle: M::ManagedBufferHandle, byte_start: usize, byte_end: usize, _phantom: PhantomData

, @@ -40,6 +40,11 @@ where _phantom: PhantomData, } } + + pub fn remaining_count(&self) -> usize { + let size = P::payload_size(); + (self.byte_end - self.byte_start) / size + } } impl Iterator for ManagedVecPayloadIterator @@ -67,8 +72,7 @@ where } fn size_hint(&self) -> (usize, Option) { - let size = P::payload_size(); - let remaining = (self.byte_end - self.byte_start) / size; + let remaining = self.remaining_count(); (remaining, Some(remaining)) } } From 56f2dc56e04022629d460e935400cdec1ba6a0a4 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 5 Dec 2024 15:31:19 +0200 Subject: [PATCH 069/133] EgldOrEsdtTokenIdentifier/TokenIdentifier refactor --- .../wrappers/call_value_wrapper.rs | 4 +- framework/base/src/types/managed/wrapped.rs | 2 +- .../wrapped/egld_or_esdt_token_identifier.rs | 159 ++++++++++++++---- .../types/managed/wrapped/token_identifier.rs | 68 ++++---- 4 files changed, 166 insertions(+), 67 deletions(-) diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index a1f44e026e..777d8bdcf8 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -10,12 +10,10 @@ use crate::{ BigUint, ConstDecimals, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, EsdtTokenPayment, ManagedDecimal, ManagedRef, ManagedType, ManagedVec, ManagedVecItem, ManagedVecItemPayload, ManagedVecPayloadIterator, - ManagedVecRef, TokenIdentifier, + ManagedVecRef, TokenIdentifier, EGLD_000000_TOKEN_IDENTIFIER, }, }; -const EGLD_000000_TOKEN_IDENTIFIER: &str = "EGLD-000000"; - #[derive(Default)] pub struct CallValueWrapper where diff --git a/framework/base/src/types/managed/wrapped.rs b/framework/base/src/types/managed/wrapped.rs index 52d827c79f..679890964b 100644 --- a/framework/base/src/types/managed/wrapped.rs +++ b/framework/base/src/types/managed/wrapped.rs @@ -31,7 +31,7 @@ mod traits; pub use big_uint::BigUint; pub use builder::*; -pub use egld_or_esdt_token_identifier::EgldOrEsdtTokenIdentifier; +pub use egld_or_esdt_token_identifier::{EgldOrEsdtTokenIdentifier, EGLD_000000_TOKEN_IDENTIFIER}; pub use egld_or_esdt_token_payment::{EgldOrEsdtTokenPayment, EgldOrEsdtTokenPaymentRefs}; pub use egld_or_multi_esdt_payment::{EgldOrMultiEsdtPayment, EgldOrMultiEsdtPaymentRefs}; pub(crate) use encoded_managed_vec_item::EncodedManagedVecItem; diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index 7b46cb2e50..8dc341f657 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -2,16 +2,21 @@ use alloc::string::ToString; use crate::{ abi::{TypeAbi, TypeAbiFrom, TypeName}, - api::{HandleConstraints, ManagedTypeApi}, + api::{ + const_handles, use_raw_handle, ErrorApiImpl, HandleConstraints, ManagedBufferApiImpl, + ManagedTypeApi, + }, codec::*, derive::ManagedVecItem, formatter::{FormatByteReceiver, SCDisplay, SCLowerHex}, proxy_imports::TestTokenIdentifier, - types::{ManagedBuffer, ManagedOption, ManagedRef, ManagedType, TokenIdentifier}, + types::{ManagedBuffer, ManagedRef, ManagedType, TokenIdentifier}, }; use crate as multiversx_sc; // required by the ManagedVecItem derive +pub const EGLD_000000_TOKEN_IDENTIFIER: &str = "EGLD-000000"; + /// Specialized type for handling either EGLD or ESDT token identifiers. /// /// Equivalent to a structure of the form @@ -30,19 +35,45 @@ use crate as multiversx_sc; // required by the ManagedVecItem derive #[repr(transparent)] #[derive(ManagedVecItem, Clone)] pub struct EgldOrEsdtTokenIdentifier { - pub(crate) data: ManagedOption>, + pub(crate) buffer: ManagedBuffer, +} + +impl ManagedType for EgldOrEsdtTokenIdentifier { + type OwnHandle = M::ManagedBufferHandle; + + #[inline] + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { + EgldOrEsdtTokenIdentifier { + buffer: ManagedBuffer::from_handle(handle), + } + } + + fn get_handle(&self) -> M::ManagedBufferHandle { + self.buffer.get_handle() + } + + unsafe fn forget_into_handle(self) -> Self::OwnHandle { + self.buffer.forget_into_handle() + } + + fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { + unsafe { core::mem::transmute(handle_ref) } + } + + fn transmute_from_handle_ref_mut(handle_ref: &mut M::ManagedBufferHandle) -> &mut Self { + unsafe { core::mem::transmute(handle_ref) } + } } impl EgldOrEsdtTokenIdentifier { /// This special representation is interpreted as the EGLD token. - #[allow(clippy::needless_borrow)] // clippy is wrog here, there is no other way - pub const EGLD_REPRESENTATION: &'static [u8; 4] = &b"EGLD"; + pub const EGLD_REPRESENTATION: &'static [u8; 4] = b"EGLD"; /// New instance of the special EGLD token representation. #[inline] pub fn egld() -> Self { - Self { - data: ManagedOption::none(), + EgldOrEsdtTokenIdentifier { + buffer: ManagedBuffer::from(EGLD_000000_TOKEN_IDENTIFIER), } } @@ -52,30 +83,36 @@ impl EgldOrEsdtTokenIdentifier { where TokenIdentifier: From, { - Self { - data: ManagedOption::some(TokenIdentifier::from(token_identifier)), - } + let ti_obj = TokenIdentifier::from(token_identifier); + ti_obj.data } pub fn parse(data: ManagedBuffer) -> Self { if data == Self::EGLD_REPRESENTATION { Self::egld() } else { - Self::esdt(TokenIdentifier::from(data)) + Self { buffer: data } } } #[inline] pub fn is_egld(&self) -> bool { - self.data.is_none() + M::managed_type_impl().mb_overwrite( + use_raw_handle(const_handles::MBUF_EGLD_000000), + EGLD_000000_TOKEN_IDENTIFIER.as_bytes(), + ); + M::managed_type_impl().mb_eq( + use_raw_handle(const_handles::MBUF_EGLD_000000), + self.buffer.handle.clone(), + ) } #[inline] pub fn is_esdt(&self) -> bool { - self.data.is_some() + !self.is_egld() } - #[inline] + /// Returns "EGLD" or the token identifier. pub fn into_name(self) -> ManagedBuffer { self.map_or_else( (), @@ -95,12 +132,31 @@ impl EgldOrEsdtTokenIdentifier { ) } + #[inline] + pub fn into_managed_buffer(self) -> ManagedBuffer { + self.buffer + } + + #[inline] + pub fn as_managed_buffer(&self) -> &ManagedBuffer { + &self.buffer + } + + #[inline] + pub fn to_boxed_bytes(&self) -> crate::types::heap::BoxedBytes { + self.buffer.to_boxed_bytes() + } + pub fn map_or_else(self, context: Context, for_egld: D, for_esdt: F) -> R where D: FnOnce(Context) -> R, F: FnOnce(Context, TokenIdentifier) -> R, { - self.data.map_or_else(context, for_egld, for_esdt) + if self.is_egld() { + for_egld(context) + } else { + unsafe { for_esdt(context, TokenIdentifier::esdt_unchecked(self)) } + } } pub fn map_ref_or_else(&self, context: Context, for_egld: D, for_esdt: F) -> R @@ -108,30 +164,65 @@ impl EgldOrEsdtTokenIdentifier { D: FnOnce(Context) -> R, F: FnOnce(Context, &TokenIdentifier) -> R, { - self.data.map_ref_or_else(context, for_egld, for_esdt) + if self.is_egld() { + for_egld(context) + } else { + unsafe { + let token_identifier = + ManagedRef::<'_, M, TokenIdentifier>::wrap_handle(self.get_handle()); + for_esdt(context, &token_identifier) + } + } } pub fn unwrap_esdt(self) -> TokenIdentifier { - self.data.unwrap_or_sc_panic("ESDT expected") + self.map_or_else( + (), + |()| M::error_api_impl().signal_error(b"ESDT expected"), + |(), token_identifier| token_identifier, + ) } /// Representation of the object as an `Option`. /// /// Because it does not consume `self` only a reference to the ESDT token identifier can be returned. pub fn as_esdt_option(&self) -> Option>> { - self.data.as_option() + if self.is_egld() { + None + } else { + unsafe { + Some(ManagedRef::<'_, M, TokenIdentifier>::wrap_handle( + self.get_handle(), + )) + } + } } /// Converts `self` into an `Option`. Consumes `self` in the process. pub fn into_esdt_option(self) -> Option> { - self.data.into_option() + self.map_or_else((), |()| None, |(), token_identifier| Some(token_identifier)) + } +} + +impl From> for EgldOrEsdtTokenIdentifier { + #[inline] + fn from(buffer: ManagedBuffer) -> Self { + EgldOrEsdtTokenIdentifier { buffer } + } +} + +impl From<&[u8]> for EgldOrEsdtTokenIdentifier { + fn from(bytes: &[u8]) -> Self { + EgldOrEsdtTokenIdentifier { + buffer: ManagedBuffer::new_from_bytes(bytes), + } } } impl PartialEq for EgldOrEsdtTokenIdentifier { #[inline] fn eq(&self, other: &Self) -> bool { - self.data == other.data + self.buffer == other.buffer } } @@ -155,10 +246,10 @@ impl NestedEncode for EgldOrEsdtTokenIdentifier { O: NestedEncodeOutput, H: EncodeErrorHandler, { - if let Some(token_identifier) = self.data.as_option() { - token_identifier.dep_encode_or_handle_err(dest, h) - } else { + if self.is_egld() { (&Self::EGLD_REPRESENTATION[..]).dep_encode_or_handle_err(dest, h) + } else { + self.buffer.dep_encode_or_handle_err(dest, h) } } } @@ -170,10 +261,10 @@ impl TopEncode for EgldOrEsdtTokenIdentifier { O: TopEncodeOutput, H: EncodeErrorHandler, { - if let Some(token_identifier) = self.data.as_option() { - token_identifier.top_encode_or_handle_err(output, h) - } else { + if self.is_egld() { (&Self::EGLD_REPRESENTATION[..]).top_encode_or_handle_err(output, h) + } else { + self.buffer.top_encode_or_handle_err(output, h) } } } @@ -231,12 +322,12 @@ impl TypeAbi for EgldOrEsdtTokenIdentifier { impl SCDisplay for EgldOrEsdtTokenIdentifier { fn fmt(&self, f: &mut F) { - if let Some(token_identifier) = self.data.as_option() { - let cast_handle = token_identifier.get_handle().cast_or_signal_error::(); + if self.is_egld() { + f.append_bytes(Self::EGLD_REPRESENTATION); + } else { + let cast_handle = self.buffer.get_handle().cast_or_signal_error::(); let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; f.append_managed_buffer(&wrap_cast); - } else { - f.append_bytes(Self::EGLD_REPRESENTATION); } } } @@ -245,12 +336,12 @@ const EGLD_REPRESENTATION_HEX: &[u8] = b"45474C44"; impl SCLowerHex for EgldOrEsdtTokenIdentifier { fn fmt(&self, f: &mut F) { - if let Some(token_identifier) = self.data.as_option() { - let cast_handle = token_identifier.get_handle().cast_or_signal_error::(); + if self.is_egld() { + f.append_bytes(EGLD_REPRESENTATION_HEX); + } else { + let cast_handle = self.buffer.get_handle().cast_or_signal_error::(); let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; f.append_managed_buffer_lower_hex(&wrap_cast); - } else { - f.append_bytes(EGLD_REPRESENTATION_HEX); } } } diff --git a/framework/base/src/types/managed/wrapped/token_identifier.rs b/framework/base/src/types/managed/wrapped/token_identifier.rs index 39fd17f5e1..6228fba515 100644 --- a/framework/base/src/types/managed/wrapped/token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/token_identifier.rs @@ -19,7 +19,7 @@ use super::{EgldOrEsdtTokenIdentifier, ManagedRef}; #[repr(transparent)] #[derive(Clone)] pub struct TokenIdentifier { - buffer: ManagedBuffer, + pub(crate) data: EgldOrEsdtTokenIdentifier, } impl ManagedType for TokenIdentifier { @@ -28,16 +28,16 @@ impl ManagedType for TokenIdentifier { #[inline] unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { TokenIdentifier { - buffer: ManagedBuffer::from_handle(handle), + data: EgldOrEsdtTokenIdentifier::from_handle(handle), } } fn get_handle(&self) -> M::ManagedBufferHandle { - self.buffer.get_handle() + self.data.get_handle() } unsafe fn forget_into_handle(self) -> Self::OwnHandle { - self.buffer.forget_into_handle() + self.data.forget_into_handle() } fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self { @@ -50,36 +50,44 @@ impl ManagedType for TokenIdentifier { } impl TokenIdentifier { + /// Creates a new TokenIdentifier without verifying that it is not EGLD-000000. + /// + /// ## Safety + /// + /// Calling it for the EGLD token might lead to unexpected bugs. + pub unsafe fn esdt_unchecked(data: EgldOrEsdtTokenIdentifier) -> Self { + Self { data } + } + #[inline] pub fn from_esdt_bytes>>(bytes: B) -> Self { - TokenIdentifier { - buffer: bytes.into(), - } + TokenIdentifier::from(bytes.into()) } #[inline] pub fn into_managed_buffer(self) -> ManagedBuffer { - self.buffer + self.data.into_managed_buffer() } #[inline] pub fn as_managed_buffer(&self) -> &ManagedBuffer { - &self.buffer + self.data.as_managed_buffer() } #[inline] pub fn to_boxed_bytes(&self) -> crate::types::heap::BoxedBytes { - self.buffer.to_boxed_bytes() + self.data.to_boxed_bytes() } pub fn is_valid_esdt_identifier(&self) -> bool { - M::managed_type_impl().validate_token_identifier(self.buffer.handle.clone()) + M::managed_type_impl().validate_token_identifier(self.data.buffer.handle.clone()) } pub fn ticker(&self) -> ManagedBuffer { - let token_id_len = self.buffer.len(); + let buffer = self.as_managed_buffer(); + let token_id_len = buffer.len(); let ticker_len = M::managed_type_impl().get_token_ticker_len(token_id_len); - self.buffer.copy_slice(0, ticker_len).unwrap_or_else(|| { + buffer.copy_slice(0, ticker_len).unwrap_or_else(|| { M::error_api_impl().signal_error(err_msg::BAD_TOKEN_TICKER_FORMAT.as_bytes()) }) } @@ -88,15 +96,13 @@ impl TokenIdentifier { impl From> for TokenIdentifier { #[inline] fn from(buffer: ManagedBuffer) -> Self { - TokenIdentifier { buffer } + EgldOrEsdtTokenIdentifier::from(buffer).unwrap_esdt() } } impl From<&[u8]> for TokenIdentifier { fn from(bytes: &[u8]) -> Self { - TokenIdentifier { - buffer: ManagedBuffer::new_from_bytes(bytes), - } + EgldOrEsdtTokenIdentifier::from(bytes).unwrap_esdt() } } @@ -115,7 +121,7 @@ impl From<&crate::types::heap::String> for TokenIdentifier impl PartialEq for TokenIdentifier { #[inline] fn eq(&self, other: &Self) -> bool { - self.buffer == other.buffer + self.data == other.data } } @@ -139,7 +145,7 @@ impl NestedEncode for TokenIdentifier { O: NestedEncodeOutput, H: EncodeErrorHandler, { - self.buffer.dep_encode_or_handle_err(dest, h) + self.data.dep_encode_or_handle_err(dest, h) } } @@ -150,7 +156,7 @@ impl TopEncode for TokenIdentifier { O: TopEncodeOutput, H: EncodeErrorHandler, { - self.buffer.top_encode_or_handle_err(output, h) + self.data.top_encode_or_handle_err(output, h) } } @@ -160,9 +166,11 @@ impl NestedDecode for TokenIdentifier { I: NestedDecodeInput, H: DecodeErrorHandler, { - Ok(TokenIdentifier::from( - ManagedBuffer::dep_decode_or_handle_err(input, h)?, - )) + unsafe { + Ok(TokenIdentifier::esdt_unchecked( + EgldOrEsdtTokenIdentifier::dep_decode_or_handle_err(input, h)?, + )) + } } } @@ -172,9 +180,11 @@ impl TopDecode for TokenIdentifier { I: TopDecodeInput, H: DecodeErrorHandler, { - Ok(TokenIdentifier::from( - ManagedBuffer::top_decode_or_handle_err(input, h)?, - )) + unsafe { + Ok(TokenIdentifier::esdt_unchecked( + EgldOrEsdtTokenIdentifier::top_decode_or_handle_err(input, h)?, + )) + } } } @@ -198,7 +208,7 @@ impl TypeAbi for TokenIdentifier { impl SCDisplay for TokenIdentifier { fn fmt(&self, f: &mut F) { - let cast_handle = self.buffer.get_handle().cast_or_signal_error::(); + let cast_handle = self.get_handle().cast_or_signal_error::(); let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; f.append_managed_buffer(&wrap_cast); } @@ -206,7 +216,7 @@ impl SCDisplay for TokenIdentifier { impl SCLowerHex for TokenIdentifier { fn fmt(&self, f: &mut F) { - let cast_handle = self.buffer.get_handle().cast_or_signal_error::(); + let cast_handle = self.get_handle().cast_or_signal_error::(); let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; f.append_managed_buffer_lower_hex(&wrap_cast); } @@ -214,7 +224,7 @@ impl SCLowerHex for TokenIdentifier { impl core::fmt::Display for TokenIdentifier { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let bytes = self.buffer.to_boxed_bytes(); + let bytes = self.to_boxed_bytes(); let s = alloc::string::String::from_utf8_lossy(bytes.as_slice()); s.fmt(f) } From 7f95624d1fe36aee71ca84c0e4997d67193e38ff Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 5 Dec 2024 16:16:53 +0200 Subject: [PATCH 070/133] EgldOrEsdtTokenIdentifier ManagedVecItem refactor --- .../types/managed/wrapped/egld_or_esdt_token_identifier.rs | 5 +---- framework/base/src/types/managed/wrapped/managed_vec_item.rs | 5 +++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index 8dc341f657..79b9977943 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -7,14 +7,11 @@ use crate::{ ManagedTypeApi, }, codec::*, - derive::ManagedVecItem, formatter::{FormatByteReceiver, SCDisplay, SCLowerHex}, proxy_imports::TestTokenIdentifier, types::{ManagedBuffer, ManagedRef, ManagedType, TokenIdentifier}, }; -use crate as multiversx_sc; // required by the ManagedVecItem derive - pub const EGLD_000000_TOKEN_IDENTIFIER: &str = "EGLD-000000"; /// Specialized type for handling either EGLD or ESDT token identifiers. @@ -33,7 +30,7 @@ pub const EGLD_000000_TOKEN_IDENTIFIER: &str = "EGLD-000000"; /// EGLD is indicated by a special, invalid token identifier handle. /// This way we can fit it inside a single i32 in memory. #[repr(transparent)] -#[derive(ManagedVecItem, Clone)] +#[derive(Clone)] pub struct EgldOrEsdtTokenIdentifier { pub(crate) buffer: ManagedBuffer, } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 62e62ad4dd..1148498634 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -12,8 +12,8 @@ use crate::{ }; use super::{ - ManagedVecItemNestedTuple, ManagedVecItemPayload, ManagedVecItemPayloadAdd, - ManagedVecItemPayloadBuffer, ManagedVecRef, + EgldOrEsdtTokenIdentifier, ManagedVecItemNestedTuple, ManagedVecItemPayload, + ManagedVecItemPayloadAdd, ManagedVecItemPayloadBuffer, ManagedVecRef, }; /// Types that implement this trait can be items inside a `ManagedVec`. @@ -230,6 +230,7 @@ impl_managed_type! {BigInt} impl_managed_type! {EllipticCurve} impl_managed_type! {ManagedAddress} impl_managed_type! {TokenIdentifier} +impl_managed_type! {EgldOrEsdtTokenIdentifier} impl ManagedVecItem for ManagedByteArray where From 675066cdd2a56685f045e3107f19b046cbccf79e Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Thu, 5 Dec 2024 15:20:20 +0100 Subject: [PATCH 071/133] system sc interaction and proxy, modify creator tests, set token type --- .../contract_base/wrappers/send_wrapper.rs | 26 +++--- .../base/src/types/interaction/markers.rs | 2 + .../interaction/markers/system_sc_address.rs | 75 ++++++++++++++++ .../src/types/interaction/system_proxy.rs | 2 + .../system_proxy/builtin_func_proxy.rs | 24 +----- .../system_proxy/system_sc_proxy.rs | 61 +++++++++++++ .../src/system_sc_interact.rs | 44 ++++++++-- .../tests/chain_simulator_token_tests.rs | 85 ++++++++++++++++++- 8 files changed, 278 insertions(+), 41 deletions(-) create mode 100644 framework/base/src/types/interaction/markers/system_sc_address.rs create mode 100644 framework/base/src/types/interaction/system_proxy/system_sc_proxy.rs diff --git a/framework/base/src/contract_base/wrappers/send_wrapper.rs b/framework/base/src/contract_base/wrappers/send_wrapper.rs index 09809956bb..a10041550a 100644 --- a/framework/base/src/contract_base/wrappers/send_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/send_wrapper.rs @@ -1,10 +1,8 @@ use core::marker::PhantomData; -use multiversx_chain_core::types::EsdtTokenType; - use crate::codec::Empty; -use crate::types::ManagedRef; +use crate::types::{ManagedRef, SystemSCAddress}; use crate::{ api::{BlockchainApi, CallTypeApi, StorageReadApi}, codec, @@ -55,7 +53,7 @@ where self.esdt_system_sc_tx() } - /// Prepares a proxy object to call the system SC. + /// Prepares a proxy object to call the ESDT 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, @@ -65,6 +63,16 @@ where .typed(system_proxy::ESDTSystemSCProxy) } + /// 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 system_sc_tx( + &self, + ) -> system_proxy::SystemSCProxyMethods, (), SystemSCAddress, ()> { + Tx::new_tx_from_sc() + .to(SystemSCAddress) + .typed(system_proxy::SystemSCProxy) + } + /// Convenient way to quickly instance a minimal contract call (with no EGLD, no arguments, etc.) /// /// You can further configure this contract call by chaining methods to it. @@ -766,16 +774,6 @@ where .sync_call() } - /// Sets the token type for a specific token. - pub fn esdt_set_token_type(&self, token_id: &TokenIdentifier, token_type: EsdtTokenType) { - Tx::new_tx_from_sc() - .to(ToSelf) - .gas(GasLeft) - .typed(system_proxy::UserBuiltinProxy) - .esdt_set_token_type(token_id, token_type) - .sync_call() - } - /// Modifies royalties for a specific token. pub fn esdt_modify_royalties( &self, diff --git a/framework/base/src/types/interaction/markers.rs b/framework/base/src/types/interaction/markers.rs index 4ebce757cc..c804844400 100644 --- a/framework/base/src/types/interaction/markers.rs +++ b/framework/base/src/types/interaction/markers.rs @@ -1,9 +1,11 @@ mod esdt_system_sc_address; mod gas_left; +mod system_sc_address; mod to_caller; mod to_self; pub use esdt_system_sc_address::ESDTSystemSCAddress; pub use gas_left::GasLeft; +pub use system_sc_address::SystemSCAddress; pub use to_caller::ToCaller; pub use to_self::ToSelf; diff --git a/framework/base/src/types/interaction/markers/system_sc_address.rs b/framework/base/src/types/interaction/markers/system_sc_address.rs new file mode 100644 index 0000000000..e7d5ea1642 --- /dev/null +++ b/framework/base/src/types/interaction/markers/system_sc_address.rs @@ -0,0 +1,75 @@ +use hex_literal::hex; +use multiversx_chain_core::types::Address; +use multiversx_sc_codec::{EncodeErrorHandler, TopEncode, TopEncodeOutput}; + +use crate::{ + abi::TypeAbiFrom, + api::ManagedTypeApi, + types::{AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxTo, TxToSpecified}, +}; + +/// Address of the system smart contract that manages ESDT. +const SYSTEM_SC_ADDRESS_BYTES: [u8; 32] = + hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01"); +const SYSTEM_SC_ADDRESS_BECH32: &str = + "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366"; +const SYSTEM_SC_ADDRESS_ANNOTATION: &str = + "bech32:erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366"; + +/// Indicates the system SC address, which is the same on any MultiversX blockchain. +pub struct SystemSCAddress; + +impl SystemSCAddress { + pub fn to_managed_address(self) -> ManagedAddress + where + Api: ManagedTypeApi, + { + ManagedAddress::from(SYSTEM_SC_ADDRESS_BYTES) + } + + pub fn to_address(&self) -> Address { + SYSTEM_SC_ADDRESS_BYTES.into() + } + + pub fn to_bech32_str(&self) -> &str { + SYSTEM_SC_ADDRESS_BECH32 + } + + pub fn to_bech32_string(&self) -> alloc::string::String { + SYSTEM_SC_ADDRESS_BECH32.into() + } +} + +impl AnnotatedValue> for SystemSCAddress +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + ManagedBuffer::from(SYSTEM_SC_ADDRESS_ANNOTATION) + } + + fn to_value(&self, _env: &Env) -> ManagedAddress { + SystemSCAddress.to_managed_address() + } +} + +impl TxTo for SystemSCAddress where Env: TxEnv {} +impl TxToSpecified for SystemSCAddress where Env: TxEnv {} + +impl TopEncode for SystemSCAddress { + fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> + where + O: TopEncodeOutput, + H: EncodeErrorHandler, + { + SYSTEM_SC_ADDRESS_BYTES.top_encode_or_handle_err(output, h) + } +} + +impl TypeAbiFrom for ManagedAddress where M: ManagedTypeApi {} + +impl core::fmt::Display for SystemSCAddress { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(SYSTEM_SC_ADDRESS_BECH32) + } +} diff --git a/framework/base/src/types/interaction/system_proxy.rs b/framework/base/src/types/interaction/system_proxy.rs index e86c9f32ff..d6a3e084be 100644 --- a/framework/base/src/types/interaction/system_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy.rs @@ -1,9 +1,11 @@ mod builtin_func_proxy; mod esdt_system_sc_proxy; mod legacy_system_sc_proxy; +mod system_sc_proxy; pub(crate) mod token_properties; pub use builtin_func_proxy::*; pub use esdt_system_sc_proxy::{ESDTSystemSCProxy, ESDTSystemSCProxyMethods, IssueCall}; pub use legacy_system_sc_proxy::ESDTSystemSmartContractProxy; +pub use system_sc_proxy::{SystemSCProxy, SystemSCProxyMethods}; pub use token_properties::*; diff --git a/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs b/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs index 8388332d75..601f978393 100644 --- a/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs @@ -1,8 +1,8 @@ use multiversx_sc_codec::{Empty, TopEncode}; use crate::types::{ - BigUint, EsdtTokenType, ManagedAddress, ManagedBuffer, ManagedVec, NotPayable, ProxyArg, - TokenIdentifier, Tx, TxEnv, TxFrom, TxGas, TxProxyTrait, TxTo, TxTypedCall, + BigUint, ManagedAddress, ManagedBuffer, ManagedVec, NotPayable, ProxyArg, TokenIdentifier, Tx, + TxEnv, TxFrom, TxGas, TxProxyTrait, TxTo, TxTypedCall, }; use crate::chain_core::builtin_func_names::{ @@ -11,7 +11,7 @@ use crate::chain_core::builtin_func_names::{ ESDT_METADATA_UPDATE_FUNC_NAME, ESDT_MODIFY_CREATOR_FUNC_NAME, ESDT_MODIFY_ROYALTIES_FUNC_NAME, ESDT_NFT_ADD_QUANTITY_FUNC_NAME, ESDT_NFT_ADD_URI_FUNC_NAME, ESDT_NFT_BURN_FUNC_NAME, ESDT_NFT_CREATE_FUNC_NAME, ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME, ESDT_SET_NEW_URIS_FUNC_NAME, - ESDT_SET_TOKEN_TYPE_FUNC_NAME, SET_USERNAME_FUNC_NAME, + SET_USERNAME_FUNC_NAME, }; /// Proxy describing the user builtin function signatures. @@ -217,24 +217,6 @@ where tx.original_result() } - pub fn esdt_set_token_type< - Arg0: ProxyArg>, - Arg1: ProxyArg, - >( - self, - token_id: Arg0, - token_type: Arg1, - ) -> TxTypedCall { - let tx = self - .wrapped_tx - .payment(NotPayable) - .raw_call(ESDT_SET_TOKEN_TYPE_FUNC_NAME) - .argument(&token_id) - .argument(&token_type); - - tx.original_result() - } - pub fn esdt_modify_royalties< Arg0: ProxyArg>, Arg1: ProxyArg, diff --git a/framework/base/src/types/interaction/system_proxy/system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/system_sc_proxy.rs new file mode 100644 index 0000000000..1e5b3af66b --- /dev/null +++ b/framework/base/src/types/interaction/system_proxy/system_sc_proxy.rs @@ -0,0 +1,61 @@ +use multiversx_chain_core::builtin_func_names::ESDT_SET_TOKEN_TYPE_FUNC_NAME; + +use crate::types::{ + EsdtTokenType, NotPayable, ProxyArg, TokenIdentifier, Tx, TxEnv, TxFrom, TxGas, TxProxyTrait, + TxTo, TxTypedCall, +}; + +/// Proxy for the system smart contract. +pub struct SystemSCProxy; + +impl TxProxyTrait for SystemSCProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = SystemSCProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + SystemSCProxyMethods { wrapped_tx: tx } + } +} + +/// Method container of the ESDT system smart contract proxy. +pub struct SystemSCProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +impl SystemSCProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + /// Sets the token type for a specific token. + pub fn esdt_set_token_type< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + token_id: Arg0, + token_type: Arg1, + ) -> TxTypedCall { + let tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_SET_TOKEN_TYPE_FUNC_NAME) + .argument(&token_id) + .argument(&token_type); + + tx.original_result() + } +} diff --git a/tools/interactor-system-func-calls/src/system_sc_interact.rs b/tools/interactor-system-func-calls/src/system_sc_interact.rs index 28ecc05034..c3a81c29de 100644 --- a/tools/interactor-system-func-calls/src/system_sc_interact.rs +++ b/tools/interactor-system-func-calls/src/system_sc_interact.rs @@ -224,6 +224,7 @@ pub async fn system_sc_interact_cli() { pub struct SysFuncCallsInteract { interactor: Interactor, wallet_address: Bech32Address, + other_wallet_address: Bech32Address, #[allow(unused)] state: State, } @@ -236,6 +237,7 @@ impl SysFuncCallsInteract { interactor.set_current_dir_from_workspace("tools/interactor-system-func-calls"); let wallet_address = interactor.register_wallet(test_wallets::alice()).await; + let other_wallet_address = interactor.register_wallet(test_wallets::mike()).await; // generate blocks until ESDTSystemSCAddress is enabled interactor.generate_blocks_until_epoch(1).await.unwrap(); @@ -243,6 +245,7 @@ impl SysFuncCallsInteract { Self { interactor, wallet_address: wallet_address.into(), + other_wallet_address: other_wallet_address.into(), state: State::load_state(), } } @@ -426,6 +429,25 @@ impl SysFuncCallsInteract { token_id } + pub async fn set_roles_for_other(&mut self, token_id: &[u8], roles: Vec) { + let wallet_address = &self.other_wallet_address.clone().into_address(); + println!("Setting the following roles: {roles:?} for {token_id:?} for other_address"); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .set_special_roles( + ManagedAddress::from_address(wallet_address), + TokenIdentifier::from(token_id), + roles.into_iter(), + ) + .run() + .await; + } + pub async fn set_roles(&mut self, token_id: &[u8], roles: Vec) { let wallet_address = &self.wallet_address.clone().into_address(); println!("Setting the following roles: {roles:?} for {token_id:?}"); @@ -812,9 +834,9 @@ impl SysFuncCallsInteract { self.interactor .tx() .from(&self.wallet_address) - .to(&self.wallet_address) + .to(SystemSCAddress) .gas(100_000_000u64) - .typed(UserBuiltinProxy) + .typed(SystemSCProxy) .esdt_set_token_type(token_id, token_type) .run() .await; @@ -853,16 +875,28 @@ impl SysFuncCallsInteract { .await; } + pub async fn send_esdt(&mut self, token_id: &[u8], nonce: u64, amount: RustBigUint) { + println!("Sending token {token_id:?} with nonce {nonce:?} to other_wallet_address..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.other_wallet_address) + .single_esdt(&token_id.into(), nonce, &amount.into()) // .transfer() + .run() + .await; + } + // changes creator into caller pub async fn modify_creator(&mut self, token_id: &[u8], nonce: u64) { println!( - "Modifying the creator (into caller) for token {token_id:?} with nonce {nonce:?}..." + "Modifying the creator (into caller - other_wallet_address) for token {token_id:?} with nonce {nonce:?}..." ); self.interactor .tx() - .from(&self.wallet_address) - .to(&self.wallet_address) + .from(&self.other_wallet_address) + .to(&self.other_wallet_address) .gas(100_000_000u64) .typed(UserBuiltinProxy) .esdt_nft_modify_creator(token_id, nonce) diff --git a/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs index ba0f83c9f7..42cb4fa5c8 100644 --- a/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs +++ b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs @@ -1,4 +1,4 @@ -use multiversx_sc_snippets::imports::{EsdtTokenType, RustBigUint}; +use multiversx_sc_snippets::imports::{EsdtLocalRole, EsdtTokenType, RustBigUint}; use system_sc_interact::{Config, NftDummyAttributes, SysFuncCallsInteract}; const ISSUE_COST: u64 = 50000000000000000u64; @@ -213,3 +213,86 @@ async fn update_token_test() { // update NFT interact.update_token(nft_token_id.as_bytes()).await; } + +#[tokio::test] +#[ignore = "run on demand"] +async fn set_token_type_test() { + let mut interact = SysFuncCallsInteract::init(Config::load_config()).await; + + // issue dynamic SFT with all roles + let dynamic_sft_token_id = interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 0usize, + EsdtTokenType::DynamicSFT, + ) + .await; + + // set token type to dynamicMeta + interact + .set_token_type(dynamic_sft_token_id.as_bytes(), EsdtTokenType::DynamicMeta) + .await; +} + +#[tokio::test] +#[ignore = "run on demand"] +async fn modify_creator() { + let mut interact = SysFuncCallsInteract::init(Config::load_config()).await; + + // issue dynamic NFT + let dynamic_nft_token_id = interact + .issue_dynamic_token( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + EsdtTokenType::DynamicNFT, + 0usize, + ) + .await; + + // set roles + interact + .set_roles( + dynamic_nft_token_id.as_bytes(), + vec![EsdtLocalRole::NftCreate], + ) + .await; + + // mint NFT + let nonce = interact + .mint_nft( + dynamic_nft_token_id.as_bytes(), + RustBigUint::from(1u64), + b"myNFT", + 30u64, + b"", + &NftDummyAttributes { + creation_epoch: 2u64, + cool_factor: 3u8, + }, + Vec::new(), + ) + .await; + + println!("Dynamic NFT minted at nonce {nonce:?}"); + + // set roles for other_address + interact + .set_roles_for_other( + dynamic_nft_token_id.as_bytes(), + vec![EsdtLocalRole::ModifyCreator], + ) + .await; + + // send to other_address + interact + .send_esdt(dynamic_nft_token_id.as_bytes(), 1u64, 1u64.into()) + .await; + + // modify creator + interact + .modify_creator(dynamic_nft_token_id.as_bytes(), nonce) + .await; +} From a2e6d34b0643e8373eefd6541d17c44791e14f64 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Fri, 6 Dec 2024 10:51:59 +0100 Subject: [PATCH 072/133] removed system sc proxy and interaction along with setTokenType, can be called by meta only --- .../contract_base/wrappers/send_wrapper.rs | 12 +-- .../base/src/types/interaction/markers.rs | 2 - .../interaction/markers/system_sc_address.rs | 75 ------------------- .../src/system_sc_interact.rs | 14 ---- .../tests/chain_simulator_token_tests.rs | 22 ------ 5 files changed, 1 insertion(+), 124 deletions(-) delete mode 100644 framework/base/src/types/interaction/markers/system_sc_address.rs diff --git a/framework/base/src/contract_base/wrappers/send_wrapper.rs b/framework/base/src/contract_base/wrappers/send_wrapper.rs index a10041550a..9fe01f232a 100644 --- a/framework/base/src/contract_base/wrappers/send_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/send_wrapper.rs @@ -2,7 +2,7 @@ use core::marker::PhantomData; use crate::codec::Empty; -use crate::types::{ManagedRef, SystemSCAddress}; +use crate::types::ManagedRef; use crate::{ api::{BlockchainApi, CallTypeApi, StorageReadApi}, codec, @@ -63,16 +63,6 @@ where .typed(system_proxy::ESDTSystemSCProxy) } - /// 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 system_sc_tx( - &self, - ) -> system_proxy::SystemSCProxyMethods, (), SystemSCAddress, ()> { - Tx::new_tx_from_sc() - .to(SystemSCAddress) - .typed(system_proxy::SystemSCProxy) - } - /// Convenient way to quickly instance a minimal contract call (with no EGLD, no arguments, etc.) /// /// You can further configure this contract call by chaining methods to it. diff --git a/framework/base/src/types/interaction/markers.rs b/framework/base/src/types/interaction/markers.rs index c804844400..4ebce757cc 100644 --- a/framework/base/src/types/interaction/markers.rs +++ b/framework/base/src/types/interaction/markers.rs @@ -1,11 +1,9 @@ mod esdt_system_sc_address; mod gas_left; -mod system_sc_address; mod to_caller; mod to_self; pub use esdt_system_sc_address::ESDTSystemSCAddress; pub use gas_left::GasLeft; -pub use system_sc_address::SystemSCAddress; pub use to_caller::ToCaller; pub use to_self::ToSelf; diff --git a/framework/base/src/types/interaction/markers/system_sc_address.rs b/framework/base/src/types/interaction/markers/system_sc_address.rs deleted file mode 100644 index e7d5ea1642..0000000000 --- a/framework/base/src/types/interaction/markers/system_sc_address.rs +++ /dev/null @@ -1,75 +0,0 @@ -use hex_literal::hex; -use multiversx_chain_core::types::Address; -use multiversx_sc_codec::{EncodeErrorHandler, TopEncode, TopEncodeOutput}; - -use crate::{ - abi::TypeAbiFrom, - api::ManagedTypeApi, - types::{AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxTo, TxToSpecified}, -}; - -/// Address of the system smart contract that manages ESDT. -const SYSTEM_SC_ADDRESS_BYTES: [u8; 32] = - hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01"); -const SYSTEM_SC_ADDRESS_BECH32: &str = - "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366"; -const SYSTEM_SC_ADDRESS_ANNOTATION: &str = - "bech32:erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366"; - -/// Indicates the system SC address, which is the same on any MultiversX blockchain. -pub struct SystemSCAddress; - -impl SystemSCAddress { - pub fn to_managed_address(self) -> ManagedAddress - where - Api: ManagedTypeApi, - { - ManagedAddress::from(SYSTEM_SC_ADDRESS_BYTES) - } - - pub fn to_address(&self) -> Address { - SYSTEM_SC_ADDRESS_BYTES.into() - } - - pub fn to_bech32_str(&self) -> &str { - SYSTEM_SC_ADDRESS_BECH32 - } - - pub fn to_bech32_string(&self) -> alloc::string::String { - SYSTEM_SC_ADDRESS_BECH32.into() - } -} - -impl AnnotatedValue> for SystemSCAddress -where - Env: TxEnv, -{ - fn annotation(&self, _env: &Env) -> ManagedBuffer { - ManagedBuffer::from(SYSTEM_SC_ADDRESS_ANNOTATION) - } - - fn to_value(&self, _env: &Env) -> ManagedAddress { - SystemSCAddress.to_managed_address() - } -} - -impl TxTo for SystemSCAddress where Env: TxEnv {} -impl TxToSpecified for SystemSCAddress where Env: TxEnv {} - -impl TopEncode for SystemSCAddress { - fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> - where - O: TopEncodeOutput, - H: EncodeErrorHandler, - { - SYSTEM_SC_ADDRESS_BYTES.top_encode_or_handle_err(output, h) - } -} - -impl TypeAbiFrom for ManagedAddress where M: ManagedTypeApi {} - -impl core::fmt::Display for SystemSCAddress { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(SYSTEM_SC_ADDRESS_BECH32) - } -} diff --git a/tools/interactor-system-func-calls/src/system_sc_interact.rs b/tools/interactor-system-func-calls/src/system_sc_interact.rs index c3a81c29de..1e7c8ec1df 100644 --- a/tools/interactor-system-func-calls/src/system_sc_interact.rs +++ b/tools/interactor-system-func-calls/src/system_sc_interact.rs @@ -828,20 +828,6 @@ impl SysFuncCallsInteract { .await; } - pub async fn set_token_type(&mut self, token_id: &[u8], token_type: EsdtTokenType) { - println!("Setting token type to {token_type:?} for token {token_id:?}..."); - - self.interactor - .tx() - .from(&self.wallet_address) - .to(SystemSCAddress) - .gas(100_000_000u64) - .typed(SystemSCProxy) - .esdt_set_token_type(token_id, token_type) - .run() - .await; - } - pub async fn modify_royalties(&mut self, token_id: &[u8], nonce: u64, new_royalty: u64) { println!("Modifying royalties for token {token_id:?} into {new_royalty:?}..."); diff --git a/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs index 42cb4fa5c8..f950dc7592 100644 --- a/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs +++ b/tools/interactor-system-func-calls/tests/chain_simulator_token_tests.rs @@ -214,28 +214,6 @@ async fn update_token_test() { interact.update_token(nft_token_id.as_bytes()).await; } -#[tokio::test] -#[ignore = "run on demand"] -async fn set_token_type_test() { - let mut interact = SysFuncCallsInteract::init(Config::load_config()).await; - - // issue dynamic SFT with all roles - let dynamic_sft_token_id = interact - .issue_token_all_roles( - RustBigUint::from(ISSUE_COST), - b"TESTNFT", - b"TEST", - 0usize, - EsdtTokenType::DynamicSFT, - ) - .await; - - // set token type to dynamicMeta - interact - .set_token_type(dynamic_sft_token_id.as_bytes(), EsdtTokenType::DynamicMeta) - .await; -} - #[tokio::test] #[ignore = "run on demand"] async fn modify_creator() { From 4e07c513789182445b5ff775742504eebac35fa3 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 6 Dec 2024 19:25:17 +0200 Subject: [PATCH 073/133] call value - all_esdt_transfers backwards compatibility --- .../wrappers/call_value_wrapper.rs | 65 ++++++++++++------- .../wrapped/egld_or_esdt_token_payment.rs | 37 ++++++++++- 2 files changed, 77 insertions(+), 25 deletions(-) diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 777d8bdcf8..30f7119876 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -3,7 +3,7 @@ use core::marker::PhantomData; use crate::{ api::{ const_handles, use_raw_handle, CallValueApi, CallValueApiImpl, ErrorApi, ErrorApiImpl, - HandleConstraints, ManagedBufferApiImpl, ManagedTypeApi, StaticVarApiImpl, + HandleConstraints, ManagedBufferApiImpl, ManagedTypeApi, RawHandle, StaticVarApiImpl, }, err_msg, types::{ @@ -35,14 +35,8 @@ where /// Retrieves the EGLD call value from the VM. /// Will return 0 in case of an ESDT transfer (cannot have both EGLD and ESDT transfer simultaneously). pub fn egld_value(&self) -> ManagedRef<'static, A, BigUint> { - let mut call_value_handle: A::BigIntHandle = - use_raw_handle(A::static_var_api_impl().get_call_value_egld_handle()); - if call_value_handle == const_handles::UNINITIALIZED_HANDLE { - call_value_handle = use_raw_handle(const_handles::CALL_VALUE_EGLD); - A::static_var_api_impl().set_call_value_egld_handle(call_value_handle.get_raw_handle()); - A::call_value_api_impl().load_egld_value(call_value_handle.clone()); - } - unsafe { ManagedRef::wrap_handle(call_value_handle) } + let (egld_amount_handle, _) = load_all_call_data::(); + unsafe { ManagedRef::wrap_handle(egld_amount_handle) } } /// Returns the EGLD call value from the VM as ManagedDecimal @@ -60,11 +54,18 @@ where let egld_payment = find_egld_000000_transfer::(call_value_handle.clone()); if egld_payment.is_some() { - A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_ESDT_TRANSFERS.as_bytes()) + A::error_api_impl().signal_error(err_msg::ESDT_UNEXPECTED_EGLD.as_bytes()) } unsafe { ManagedRef::wrap_handle(call_value_handle) } } + pub fn all_transfers( + &self, + ) -> ManagedRef<'static, A, ManagedVec>> { + let (_, all_transfers_handle) = load_all_call_data::(); + unsafe { ManagedRef::wrap_handle(all_transfers_handle) } + } + /// Verify and casts the received multi ESDT transfer in to an array. /// /// Can be used to extract all payments in one line like this: @@ -168,20 +169,18 @@ fn load_all_transfers() -> A::ManagedBufferHandle where A: CallValueApi + ErrorApi + ManagedTypeApi, { - let mut call_value_handle: A::ManagedBufferHandle = + let mut all_transfers_handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().get_call_value_multi_esdt_handle()); - if call_value_handle == const_handles::UNINITIALIZED_HANDLE { - call_value_handle = use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT); + if all_transfers_handle == const_handles::UNINITIALIZED_HANDLE { + all_transfers_handle = use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT); A::static_var_api_impl() - .set_call_value_multi_esdt_handle(call_value_handle.get_raw_handle()); - A::call_value_api_impl().load_all_esdt_transfers(call_value_handle.clone()); + .set_call_value_multi_esdt_handle(all_transfers_handle.get_raw_handle()); + A::call_value_api_impl().load_all_esdt_transfers(all_transfers_handle.clone()); } - call_value_handle + all_transfers_handle } -fn find_egld_000000_transfer( - transfers_vec_handle: A::ManagedBufferHandle, -) -> Option +fn find_egld_000000_transfer(transfers_vec_handle: A::ManagedBufferHandle) -> Option where A: CallValueApi + ErrorApi + ManagedTypeApi, { @@ -201,16 +200,34 @@ where } let egld_payload = iter.find(|payload| { - let token_identifier_handle = i32::read_from_payload(payload.slice_unchecked(0)); + let token_identifier_handle = RawHandle::read_from_payload(payload.slice_unchecked(0)); A::managed_type_impl().mb_eq( use_raw_handle(const_handles::MBUF_EGLD_000000), use_raw_handle(token_identifier_handle), ) }); - egld_payload.map(|payload| { - let amount_handle = i32::read_from_payload(payload.slice_unchecked(12)); - use_raw_handle(amount_handle) - }) + egld_payload.map(|payload| RawHandle::read_from_payload(payload.slice_unchecked(12))) } } + +fn load_all_call_data() -> (A::BigIntHandle, A::ManagedBufferHandle) +where + A: CallValueApi + ErrorApi + ManagedTypeApi, +{ + let all_transfers_handle = load_all_transfers::(); + let mut egld_amount_handle: A::BigIntHandle = + use_raw_handle(A::static_var_api_impl().get_call_value_egld_handle()); + if egld_amount_handle == const_handles::UNINITIALIZED_HANDLE { + let egld_payment = find_egld_000000_transfer::(all_transfers_handle.clone()); + if let Some(egld_amount_raw_handle) = egld_payment { + egld_amount_handle = use_raw_handle(egld_amount_raw_handle); + } else { + egld_amount_handle = use_raw_handle(const_handles::CALL_VALUE_EGLD); + A::call_value_api_impl().load_egld_value(egld_amount_handle.clone()); + } + A::static_var_api_impl().set_call_value_egld_handle(egld_amount_handle.get_raw_handle()); + } + + (egld_amount_handle, all_transfers_handle) +} diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs index e87d520981..97a6d1261a 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs @@ -12,7 +12,11 @@ use crate::codec::{ use crate as multiversx_sc; // needed by the TypeAbi generated code use crate::derive::type_abi; -use super::{EsdtTokenPayment, EsdtTokenPaymentRefs}; +use super::{ + managed_vec_item_read_from_payload_index, managed_vec_item_save_to_payload_index, + EsdtTokenPayment, EsdtTokenPaymentRefs, ManagedVecItem, ManagedVecItemPayloadBuffer, + ManagedVecRef, +}; #[type_abi] #[derive(TopDecode, TopEncode, NestedDecode, NestedEncode, Clone, PartialEq, Eq, Debug)] @@ -182,3 +186,34 @@ impl<'a, M: ManagedTypeApi> EgldOrEsdtTokenPaymentRefs<'a, M> { ) } } + +impl ManagedVecItem for EgldOrEsdtTokenPayment { + type PAYLOAD = ManagedVecItemPayloadBuffer<16>; + const SKIPS_RESERIALIZATION: bool = false; + type Ref<'a> = ManagedVecRef<'a, Self>; + + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + let mut index = 0; + unsafe { + EgldOrEsdtTokenPayment { + token_identifier: managed_vec_item_read_from_payload_index(payload, &mut index), + token_nonce: managed_vec_item_read_from_payload_index(payload, &mut index), + amount: managed_vec_item_read_from_payload_index(payload, &mut index), + } + } + } + + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + ManagedVecRef::new(Self::read_from_payload(payload)) + } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let mut index = 0; + + unsafe { + managed_vec_item_save_to_payload_index(self.token_identifier, payload, &mut index); + managed_vec_item_save_to_payload_index(self.token_nonce, payload, &mut index); + managed_vec_item_save_to_payload_index(self.amount, payload, &mut index); + } + } +} From c22b035c3338284a1f136df55bfbbfdcb7d7ea58 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sat, 7 Dec 2024 03:09:19 +0200 Subject: [PATCH 074/133] lldb pretty print fix --- .../multiversx_sc_lldb_pretty_printers.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py b/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py index 297c4c50be..6b397868cd 100644 --- a/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py +++ b/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py @@ -331,7 +331,7 @@ def value_summary(self, big_uint: lldb.value, context: lldb.value, type_info: ll class TokenIdentifier(PlainManagedVecItem, ManagedType): def lookup(self, token_identifier: lldb.value) -> lldb.value: - return token_identifier.buffer + return token_identifier.data.buffer def value_summary(self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: return buffer_as_string(buffer) @@ -417,14 +417,13 @@ def to_string(self, token_id: str, nonce: int, amount: str) -> str: class EgldOrEsdtTokenIdentifier(PlainManagedVecItem, ManagedType): def lookup(self, egld_or_esdt_token_identifier: lldb.value) -> lldb.value: - return egld_or_esdt_token_identifier.data + return egld_or_esdt_token_identifier.buffer - @check_invalid_handle - def summary_from_raw_handle(self, raw_handle: int, context: lldb.value, type_info: lldb.SBType) -> str: - if raw_handle == MANAGED_OPTION_NONE_HANDLE: + def value_summary(self, buffer: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: + token_id = buffer_as_string(buffer) + if token_id == '"EGLD-000000"': return "EgldOrEsdtTokenIdentifier::egld()" - token_summary = TokenIdentifier().summary_from_raw_handle(raw_handle, context, None) - return f"EgldOrEsdtTokenIdentifier::esdt({token_summary})" + return f"EgldOrEsdtTokenIdentifier::esdt({token_id})" class ManagedVec(PlainManagedVecItem, ManagedType): From 46a476dcf044edbf5cf30822b59a2579533d35df Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Mon, 9 Dec 2024 13:45:25 +0100 Subject: [PATCH 075/133] forwarder setup, cleanup --- chain/core/src/builtin_func_names.rs | 1 - .../forwarder/src/forwarder_main.rs | 2 + .../forwarder/src/fwd_dynamic.rs | 120 ++++++++++++++++++ .../composability/forwarder/wasm/src/lib.rs | 12 +- .../src/types/interaction/system_proxy.rs | 2 - .../system_proxy/system_sc_proxy.rs | 61 --------- 6 files changed, 132 insertions(+), 66 deletions(-) create mode 100644 contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs delete mode 100644 framework/base/src/types/interaction/system_proxy/system_sc_proxy.rs diff --git a/chain/core/src/builtin_func_names.rs b/chain/core/src/builtin_func_names.rs index 51777f201b..9ab2b202ed 100644 --- a/chain/core/src/builtin_func_names.rs +++ b/chain/core/src/builtin_func_names.rs @@ -14,7 +14,6 @@ pub const SET_USERNAME_FUNC_NAME: &str = "SetUserName"; pub const MIGRATE_USERNAME_FUNC_NAME: &str = "migrateUserName"; pub const DELETE_USERNAME_FUNC_NAME: &str = "DeleteUserName"; pub const UPGRADE_CONTRACT_FUNC_NAME: &str = "upgradeContract"; -pub const ESDT_SET_TOKEN_TYPE_FUNC_NAME: &str = "ESDTSetTokenType"; pub const ESDT_MODIFY_ROYALTIES_FUNC_NAME: &str = "ESDTModifyRoyalties"; pub const ESDT_SET_NEW_URIS_FUNC_NAME: &str = "ESDTSetNewURIs"; pub const ESDT_MODIFY_CREATOR_FUNC_NAME: &str = "ESDTModifyCreator"; diff --git a/contracts/feature-tests/composability/forwarder/src/forwarder_main.rs b/contracts/feature-tests/composability/forwarder/src/forwarder_main.rs index c6e9dcb443..fa75226891 100644 --- a/contracts/feature-tests/composability/forwarder/src/forwarder_main.rs +++ b/contracts/feature-tests/composability/forwarder/src/forwarder_main.rs @@ -7,6 +7,7 @@ pub mod fwd_call_sync; pub mod fwd_call_transf_exec; pub mod fwd_change_owner; pub mod fwd_deploy; +pub mod fwd_dynamic; pub mod fwd_esdt; pub mod fwd_nft; pub mod fwd_roles; @@ -31,6 +32,7 @@ pub trait Forwarder: + fwd_sft::ForwarderSftModule + fwd_nft::ForwarderNftModule + fwd_roles::ForwarderRolesModule + + fwd_dynamic::ForwarderDynamicModule + fwd_storage::ForwarderStorageModule { #[init] diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs b/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs new file mode 100644 index 0000000000..f7a53c8f84 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs @@ -0,0 +1,120 @@ +use crate::fwd_nft::{CallbackProxy, Color}; + +multiversx_sc::imports!(); + +#[multiversx_sc::module] +pub trait ForwarderDynamicModule: + crate::fwd_nft::ForwarderNftModule + crate::fwd_storage::ForwarderStorageModule +{ + #[payable["EGLD"]] + #[endpoint] + fn issue_dynamic_token( + &self, + token_display_name: ManagedBuffer, + token_ticker: ManagedBuffer, + token_type: EsdtTokenType, + num_decimals: usize, + ) { + let issue_cost = self.call_value().egld_value().clone_value(); + let caller = self.blockchain().get_caller(); + + self.send() + .esdt_system_sc_proxy() + .issue_dynamic( + issue_cost, + token_display_name, + token_ticker, + token_type, + num_decimals, + ) + .callback(self.callbacks().nft_issue_callback(&caller)) + .async_call_and_exit(); + } + + #[endpoint] + fn change_to_dynamic(&self, token_id: TokenIdentifier) { + self.send() + .esdt_system_sc_proxy() + .change_to_dynamic(token_id) + .sync_call(); + } + + #[endpoint] + fn update_token(&self, token_id: TokenIdentifier) { + self.send() + .esdt_system_sc_proxy() + .update_token(token_id) + .sync_call(); + } + + #[endpoint] + fn modify_royalties(&self, token_id: TokenIdentifier, nonce: u64, new_royalty: u64) { + self.send() + .esdt_modify_royalties(&token_id, nonce, new_royalty); + } + + #[endpoint] + fn set_new_uris( + &self, + token_id: TokenIdentifier, + nonce: u64, + new_uris: MultiValueEncoded, + ) { + let new_uris = new_uris.to_vec(); + self.send() + .esdt_nft_set_new_uris(&token_id, nonce, &new_uris); + } + + #[endpoint] + fn modify_creator(&self, token_id: TokenIdentifier, nonce: u64) { + self.send().esdt_nft_modify_creator(&token_id, nonce); + } + + #[endpoint] + fn metadata_recreate( + &self, + token_id: TokenIdentifier, + nonce: u64, + name: ManagedBuffer, + royalties: u64, + hash: ManagedBuffer, + new_attributes: Color, + uris: MultiValueEncoded, + ) { + let uris = uris.to_vec(); + + self.send().esdt_metadata_recreate( + token_id, + nonce, + name, + royalties, + hash, + &new_attributes, + uris, + ); + } + + #[endpoint] + fn metadata_update( + &self, + token_id: TokenIdentifier, + nonce: u64, + name: ManagedBuffer, + royalties: u64, + hash: ManagedBuffer, + new_attributes: Color, + uris: MultiValueEncoded, + ) { + let uris = uris.to_vec(); + + self.send().esdt_metadata_update( + token_id, + nonce, + name, + royalties, + hash, + &new_attributes, + uris, + ); + } +} diff --git a/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs b/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs index 74d50dd752..7b6e32ddea 100644 --- a/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs @@ -5,9 +5,9 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 69 +// Endpoints: 77 // Async Callback: 1 -// Total number of exported functions: 71 +// Total number of exported functions: 79 #![no_std] @@ -85,6 +85,14 @@ multiversx_sc_wasm_adapter::endpoints! { create_and_send => create_and_send setLocalRoles => set_local_roles unsetLocalRoles => unset_local_roles + issue_dynamic_token => issue_dynamic_token + change_to_dynamic => change_to_dynamic + update_token => update_token + modify_royalties => modify_royalties + set_new_uris => set_new_uris + modify_creator => modify_creator + metadata_recreate => metadata_recreate + metadata_update => metadata_update lastIssuedToken => last_issued_token lastErrorMessage => last_error_message ) diff --git a/framework/base/src/types/interaction/system_proxy.rs b/framework/base/src/types/interaction/system_proxy.rs index d6a3e084be..e86c9f32ff 100644 --- a/framework/base/src/types/interaction/system_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy.rs @@ -1,11 +1,9 @@ mod builtin_func_proxy; mod esdt_system_sc_proxy; mod legacy_system_sc_proxy; -mod system_sc_proxy; pub(crate) mod token_properties; pub use builtin_func_proxy::*; pub use esdt_system_sc_proxy::{ESDTSystemSCProxy, ESDTSystemSCProxyMethods, IssueCall}; pub use legacy_system_sc_proxy::ESDTSystemSmartContractProxy; -pub use system_sc_proxy::{SystemSCProxy, SystemSCProxyMethods}; pub use token_properties::*; diff --git a/framework/base/src/types/interaction/system_proxy/system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/system_sc_proxy.rs deleted file mode 100644 index 1e5b3af66b..0000000000 --- a/framework/base/src/types/interaction/system_proxy/system_sc_proxy.rs +++ /dev/null @@ -1,61 +0,0 @@ -use multiversx_chain_core::builtin_func_names::ESDT_SET_TOKEN_TYPE_FUNC_NAME; - -use crate::types::{ - EsdtTokenType, NotPayable, ProxyArg, TokenIdentifier, Tx, TxEnv, TxFrom, TxGas, TxProxyTrait, - TxTo, TxTypedCall, -}; - -/// Proxy for the system smart contract. -pub struct SystemSCProxy; - -impl TxProxyTrait for SystemSCProxy -where - Env: TxEnv, - From: TxFrom, - To: TxTo, - Gas: TxGas, -{ - type TxProxyMethods = SystemSCProxyMethods; - - fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { - SystemSCProxyMethods { wrapped_tx: tx } - } -} - -/// Method container of the ESDT system smart contract proxy. -pub struct SystemSCProxyMethods -where - Env: TxEnv, - From: TxFrom, - To: TxTo, - Gas: TxGas, -{ - wrapped_tx: Tx, -} - -impl SystemSCProxyMethods -where - Env: TxEnv, - From: TxFrom, - To: TxTo, - Gas: TxGas, -{ - /// Sets the token type for a specific token. - pub fn esdt_set_token_type< - Arg0: ProxyArg>, - Arg1: ProxyArg, - >( - self, - token_id: Arg0, - token_type: Arg1, - ) -> TxTypedCall { - let tx = self - .wrapped_tx - .payment(NotPayable) - .raw_call(ESDT_SET_TOKEN_TYPE_FUNC_NAME) - .argument(&token_id) - .argument(&token_type); - - tx.original_result() - } -} From e856a908ea066778b890a3fabf8c65461440319c Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Mon, 9 Dec 2024 14:06:30 +0100 Subject: [PATCH 076/133] proxy update --- .../forwarder/src/forwarder_proxy.rs | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs b/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs index d8ef19f3a4..964df0bf23 100644 --- a/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs +++ b/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs @@ -1171,6 +1171,169 @@ where .original_result() } + pub fn issue_dynamic_token< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + token_type: Arg2, + num_decimals: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("issue_dynamic_token") + .argument(&token_display_name) + .argument(&token_ticker) + .argument(&token_type) + .argument(&num_decimals) + .original_result() + } + + pub fn change_to_dynamic< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("change_to_dynamic") + .argument(&token_id) + .original_result() + } + + pub fn update_token< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("update_token") + .argument(&token_id) + .original_result() + } + + pub fn modify_royalties< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg, + >( + self, + token_id: Arg0, + nonce: Arg1, + new_royalty: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("modify_royalties") + .argument(&token_id) + .argument(&nonce) + .argument(&new_royalty) + .original_result() + } + + pub fn set_new_uris< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>>, + >( + self, + token_id: Arg0, + nonce: Arg1, + new_uris: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("set_new_uris") + .argument(&token_id) + .argument(&nonce) + .argument(&new_uris) + .original_result() + } + + pub fn modify_creator< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + token_id: Arg0, + nonce: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("modify_creator") + .argument(&token_id) + .argument(&nonce) + .original_result() + } + + pub fn metadata_recreate< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + Arg3: ProxyArg, + Arg4: ProxyArg>, + Arg5: ProxyArg, + Arg6: ProxyArg>>, + >( + self, + token_id: Arg0, + nonce: Arg1, + name: Arg2, + royalties: Arg3, + hash: Arg4, + new_attributes: Arg5, + uris: Arg6, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("metadata_recreate") + .argument(&token_id) + .argument(&nonce) + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&new_attributes) + .argument(&uris) + .original_result() + } + + pub fn metadata_update< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + Arg3: ProxyArg, + Arg4: ProxyArg>, + Arg5: ProxyArg, + Arg6: ProxyArg>>, + >( + self, + token_id: Arg0, + nonce: Arg1, + name: Arg2, + royalties: Arg3, + hash: Arg4, + new_attributes: Arg5, + uris: Arg6, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("metadata_update") + .argument(&token_id) + .argument(&nonce) + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&new_attributes) + .argument(&uris) + .original_result() + } + pub fn last_issued_token( self, ) -> TxTypedCall> { From 9602c1015680f317f035c30bd43e947d2697e4e4 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Mon, 9 Dec 2024 14:56:18 +0100 Subject: [PATCH 077/133] forwarder interactor setup --- Cargo.toml | 1 + .../forwarder-interactor/.gitignore | 2 + .../forwarder-interactor/Cargo.toml | 32 + .../forwarder-interactor/config.toml | 7 + .../forwarder-interactor/src/config.rs | 51 + .../forwarder-interactor/src/interact.rs | 1944 +++++++++++++++++ .../src/interactor_main.rs | 7 + .../forwarder-interactor/src/proxy.rs | 1375 ++++++++++++ .../forwarder-interactor/state.toml | 1 + .../tests/interact_cs_tests.rs | 15 + .../tests/interact_tests.rs | 13 + .../composability/forwarder/sc-config.toml | 4 + .../forwarder/src/forwarder_proxy.rs | 4 +- .../forwarder/src/fwd_call_async.rs | 2 +- .../composability/forwarder/src/fwd_nft.rs | 4 +- 15 files changed, 3457 insertions(+), 5 deletions(-) create mode 100644 contracts/feature-tests/composability/forwarder-interactor/.gitignore create mode 100644 contracts/feature-tests/composability/forwarder-interactor/Cargo.toml create mode 100644 contracts/feature-tests/composability/forwarder-interactor/config.toml create mode 100644 contracts/feature-tests/composability/forwarder-interactor/src/config.rs create mode 100644 contracts/feature-tests/composability/forwarder-interactor/src/interact.rs create mode 100644 contracts/feature-tests/composability/forwarder-interactor/src/interactor_main.rs create mode 100644 contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs create mode 100644 contracts/feature-tests/composability/forwarder-interactor/state.toml create mode 100644 contracts/feature-tests/composability/forwarder-interactor/tests/interact_cs_tests.rs create mode 100644 contracts/feature-tests/composability/forwarder-interactor/tests/interact_tests.rs diff --git a/Cargo.toml b/Cargo.toml index 3cc34e3bd4..43a83719f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -133,6 +133,7 @@ members = [ "contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child", "contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/meta", "contracts/feature-tests/composability/forwarder", + "contracts/feature-tests/composability/forwarder-interactor", "contracts/feature-tests/composability/forwarder/meta", "contracts/feature-tests/composability/forwarder-legacy", "contracts/feature-tests/composability/forwarder-legacy/meta", diff --git a/contracts/feature-tests/composability/forwarder-interactor/.gitignore b/contracts/feature-tests/composability/forwarder-interactor/.gitignore new file mode 100644 index 0000000000..5a64d09a70 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/.gitignore @@ -0,0 +1,2 @@ +# Pem files are used for interactions, but shouldn't be committed +*.pem diff --git a/contracts/feature-tests/composability/forwarder-interactor/Cargo.toml b/contracts/feature-tests/composability/forwarder-interactor/Cargo.toml new file mode 100644 index 0000000000..b8dce626fc --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "forwarder-interact" +version = "0.0.0" +authors = ["you"] +edition = "2021" +publish = false + +[[bin]] +name = "forwarder-interact" +path = "src/interactor_main.rs" + +[lib] +path = "src/interact.rs" + +[dependencies.forwarder] +path = "../forwarder" + +[dependencies.multiversx-sc-snippets] +version = "0.54.5" +path = "../../../../framework/snippets" + +[dependencies.multiversx-sc] +version = "0.54.5" +path = "../../../../framework/base" + +[dependencies] +clap = { version = "4.4.7", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } +toml = "0.8.6" + +[features] +chain-simulator-tests = [] diff --git a/contracts/feature-tests/composability/forwarder-interactor/config.toml b/contracts/feature-tests/composability/forwarder-interactor/config.toml new file mode 100644 index 0000000000..97acd5a5c6 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/config.toml @@ -0,0 +1,7 @@ + +# chain_type = 'simulator' +# gateway_uri = 'http://localhost:8085' + +chain_type = 'real' +gateway_uri = 'https://devnet-gateway.multiversx.com' + diff --git a/contracts/feature-tests/composability/forwarder-interactor/src/config.rs b/contracts/feature-tests/composability/forwarder-interactor/src/config.rs new file mode 100644 index 0000000000..2d072b4bfb --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/src/config.rs @@ -0,0 +1,51 @@ +#![allow(unused)] + +use serde::Deserialize; +use std::io::Read; + +/// Config file +const CONFIG_FILE: &str = "config.toml"; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum ChainType { + Real, + Simulator, +} + +/// Contract Interact configuration +#[derive(Debug, Deserialize)] +pub struct Config { + pub gateway_uri: String, + pub chain_type: ChainType, +} + +impl Config { + // Deserializes config from file + pub fn new() -> Self { + let mut file = std::fs::File::open(CONFIG_FILE).unwrap(); + let mut content = String::new(); + file.read_to_string(&mut content).unwrap(); + toml::from_str(&content).unwrap() + } + + pub fn chain_simulator_config() -> Self { + Config { + gateway_uri: "http://localhost:8085".to_owned(), + chain_type: ChainType::Simulator, + } + } + + // Returns the gateway URI + pub fn gateway_uri(&self) -> &str { + &self.gateway_uri + } + + // Returns if chain type is chain simulator + pub fn use_chain_simulator(&self) -> bool { + match self.chain_type { + ChainType::Real => false, + ChainType::Simulator => true, + } + } +} diff --git a/contracts/feature-tests/composability/forwarder-interactor/src/interact.rs b/contracts/feature-tests/composability/forwarder-interactor/src/interact.rs new file mode 100644 index 0000000000..b4ed599a3e --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/src/interact.rs @@ -0,0 +1,1944 @@ +#![allow(non_snake_case)] + +mod config; +mod proxy; + +use config::Config; +use multiversx_sc_snippets::imports::*; +use proxy::Color; +use serde::{Deserialize, Serialize}; +use std::{ + io::{Read, Write}, + path::Path, +}; + +const STATE_FILE: &str = "state.toml"; + +pub async fn forwarder_cli() { + env_logger::init(); + + let mut args = std::env::args(); + let _ = args.next(); + let cmd = args.next().expect("at least one argument required"); + let mut interact = ContractInteract::new().await; + match cmd.as_str() { + "deploy" => interact.deploy().await, + "send_egld" => interact.send_egld().await, + "echo_arguments_sync" => interact.echo_arguments_sync().await, + "echo_arguments_sync_twice" => interact.echo_arguments_sync_twice().await, + "forward_sync_accept_funds" => interact.forward_sync_accept_funds().await, + "forward_sync_accept_funds_rh_egld" => interact.forward_sync_accept_funds_rh_egld().await, + "forward_sync_accept_funds_rh_single_esdt" => { + interact.forward_sync_accept_funds_rh_single_esdt().await + }, + "forward_sync_accept_funds_rh_multi_esdt" => { + interact.forward_sync_accept_funds_rh_multi_esdt().await + }, + "forward_sync_accept_funds_with_fees" => { + interact.forward_sync_accept_funds_with_fees().await + }, + "forward_sync_accept_funds_then_read" => { + interact.forward_sync_accept_funds_then_read().await + }, + "forward_sync_retrieve_funds" => interact.forward_sync_retrieve_funds().await, + "forward_sync_retrieve_funds_with_accept_func" => { + interact + .forward_sync_retrieve_funds_with_accept_func() + .await + }, + "accept_funds_func" => interact.accept_funds_func().await, + "forward_sync_accept_funds_multi_transfer" => { + interact.forward_sync_accept_funds_multi_transfer().await + }, + "echo_args_async" => interact.echo_args_async().await, + "forward_async_accept_funds" => interact.forward_async_accept_funds().await, + "forward_async_accept_funds_half_payment" => { + interact.forward_async_accept_funds_half_payment().await + }, + "forward_async_accept_funds_with_fees" => { + interact.forward_async_accept_funds_with_fees().await + }, + "forward_async_retrieve_funds" => interact.forward_async_retrieve_funds().await, + "send_funds_twice" => interact.send_funds_twice().await, + "send_async_accept_multi_transfer" => interact.send_async_accept_multi_transfer().await, + "callback_data" => interact.callback_data().await, + "callback_data_at_index" => interact.callback_data_at_index().await, + "clear_callback_data" => interact.clear_callback_data().await, + "forward_transf_exec_accept_funds" => interact.forward_transf_exec_accept_funds().await, + "forward_transf_execu_accept_funds_with_fees" => { + interact.forward_transf_execu_accept_funds_with_fees().await + }, + "forward_transf_exec_accept_funds_twice" => { + interact.forward_transf_exec_accept_funds_twice().await + }, + "forward_transf_exec_accept_funds_return_values" => { + interact + .forward_transf_exec_accept_funds_return_values() + .await + }, + "transf_exec_multi_accept_funds" => interact.transf_exec_multi_accept_funds().await, + "forward_transf_exec_reject_funds_multi_transfer" => { + interact + .forward_transf_exec_reject_funds_multi_transfer() + .await + }, + "transf_exec_multi_reject_funds" => interact.transf_exec_multi_reject_funds().await, + "changeOwnerAddress" => interact.change_owner().await, + "deploy_contract" => interact.deploy_contract().await, + "deploy_two_contracts" => interact.deploy_two_contracts().await, + "deploy_vault_from_source" => interact.deploy_vault_from_source().await, + "upgradeVault" => interact.upgrade_vault().await, + "upgrade_vault_from_source" => interact.upgrade_vault_from_source().await, + "getFungibleEsdtBalance" => interact.get_fungible_esdt_balance().await, + "getCurrentNftNonce" => interact.get_current_nft_nonce().await, + "send_esdt" => interact.send_esdt().await, + "send_esdt_with_fees" => interact.send_esdt_with_fees().await, + "send_esdt_twice" => interact.send_esdt_twice().await, + "send_esdt_direct_multi_transfer" => interact.send_esdt_direct_multi_transfer().await, + "issue_fungible_token" => interact.issue_fungible_token().await, + "local_mint" => interact.local_mint().await, + "local_burn" => interact.local_burn().await, + "get_esdt_local_roles" => interact.get_esdt_local_roles().await, + "get_esdt_token_data" => interact.get_esdt_token_data().await, + "is_esdt_frozen" => interact.is_esdt_frozen().await, + "is_esdt_paused" => interact.is_esdt_paused().await, + "is_esdt_limited_transfer" => interact.is_esdt_limited_transfer().await, + "validate_token_identifier" => interact.validate_token_identifier().await, + "sft_issue" => interact.sft_issue().await, + "get_nft_balance" => interact.get_nft_balance().await, + "buy_nft" => interact.buy_nft().await, + "nft_issue" => interact.nft_issue().await, + "nft_create" => interact.nft_create().await, + "nft_create_compact" => interact.nft_create_compact().await, + "nft_add_uris" => interact.nft_add_uris().await, + "nft_update_attributes" => interact.nft_update_attributes().await, + "nft_decode_complex_attributes" => interact.nft_decode_complex_attributes().await, + "nft_add_quantity" => interact.nft_add_quantity().await, + "nft_burn" => interact.nft_burn().await, + "transfer_nft_via_async_call" => interact.transfer_nft_via_async_call().await, + "transfer_nft_and_execute" => interact.transfer_nft_and_execute().await, + "create_and_send" => interact.create_and_send().await, + "setLocalRoles" => interact.set_local_roles().await, + "unsetLocalRoles" => interact.unset_local_roles().await, + "issue_dynamic_token" => interact.issue_dynamic_token().await, + "change_to_dynamic" => interact.change_to_dynamic().await, + "update_token" => interact.update_token().await, + "modify_royalties" => interact.modify_royalties().await, + "set_new_uris" => interact.set_new_uris().await, + "modify_creator" => interact.modify_creator().await, + "metadata_recreate" => interact.metadata_recreate().await, + "metadata_update" => interact.metadata_update().await, + "lastIssuedToken" => interact.last_issued_token().await, + "lastErrorMessage" => interact.last_error_message().await, + _ => panic!("unknown command: {}", &cmd), + } +} + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct State { + contract_address: Option, +} + +impl State { + // Deserializes state from file + pub fn load_state() -> Self { + if Path::new(STATE_FILE).exists() { + let mut file = std::fs::File::open(STATE_FILE).unwrap(); + let mut content = String::new(); + file.read_to_string(&mut content).unwrap(); + toml::from_str(&content).unwrap() + } else { + Self::default() + } + } + + /// Sets the contract address + pub fn set_address(&mut self, address: Bech32Address) { + self.contract_address = Some(address); + } + + /// Returns the contract address + pub fn current_address(&self) -> &Bech32Address { + self.contract_address + .as_ref() + .expect("no known contract, deploy first") + } +} + +impl Drop for State { + // Serializes state to file + fn drop(&mut self) { + let mut file = std::fs::File::create(STATE_FILE).unwrap(); + file.write_all(toml::to_string(self).unwrap().as_bytes()) + .unwrap(); + } +} + +pub struct ContractInteract { + interactor: Interactor, + wallet_address: Address, + contract_code: BytesValue, + state: State, +} + +impl ContractInteract { + pub async fn new() -> Self { + let config = Config::new(); + let mut interactor = Interactor::new(config.gateway_uri()) + .await + .use_chain_simulator(config.use_chain_simulator()); + + interactor.set_current_dir_from_workspace("forwarder-interactor"); + let wallet_address = interactor.register_wallet(test_wallets::alice()).await; + + // Useful in the chain simulator setting + // generate blocks until ESDTSystemSCAddress is enabled + interactor.generate_blocks_until_epoch(1).await.unwrap(); + + let contract_code = BytesValue::interpret_from( + "mxsc:../forwarder/output/forwarder.mxsc.json", + &InterpreterContext::default(), + ); + + ContractInteract { + interactor, + wallet_address, + contract_code, + state: State::load_state(), + } + } + + pub async fn deploy(&mut self) { + let new_address = self + .interactor + .tx() + .from(&self.wallet_address) + .gas(300_000_000u64) + .typed(proxy::ForwarderProxy) + .init() + .code(&self.contract_code) + .returns(ReturnsNewAddress) + .run() + .await; + let new_address_bech32 = bech32::encode(&new_address); + self.state.set_address(Bech32Address::from_bech32_string( + new_address_bech32.clone(), + )); + + println!("new address: {new_address_bech32}"); + } + + pub async fn send_egld(&mut self) { + let to = bech32::decode(""); + let amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .send_egld(to, amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn echo_arguments_sync(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + let args = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .echo_arguments_sync(to, args) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn echo_arguments_sync_twice(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + let args = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .echo_arguments_sync_twice(to, args) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_sync_accept_funds(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_sync_accept_funds(to) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_sync_accept_funds_rh_egld(&mut self) { + let egld_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_sync_accept_funds_rh_egld(to) + .egld(egld_amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_sync_accept_funds_rh_single_esdt(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_sync_accept_funds_rh_single_esdt(to) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_sync_accept_funds_rh_multi_esdt(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_sync_accept_funds_rh_multi_esdt(to) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_sync_accept_funds_with_fees(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + let percentage_fees = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_sync_accept_funds_with_fees(to, percentage_fees) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_sync_accept_funds_then_read(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_sync_accept_funds_then_read(to) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_sync_retrieve_funds(&mut self) { + let to = bech32::decode(""); + let token = EgldOrEsdtTokenIdentifier::esdt(&b""[..]); + let token_nonce = 0u64; + let amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_sync_retrieve_funds(to, token, token_nonce, amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_sync_retrieve_funds_with_accept_func(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + let token = TokenIdentifier::from_esdt_bytes(&b""[..]); + let amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_sync_retrieve_funds_with_accept_func(to, token, amount) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn accept_funds_func(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .accept_funds_func() + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_sync_accept_funds_multi_transfer(&mut self) { + let to = bech32::decode(""); + let token_payments = MultiValueVec::from(vec![MultiValue3::< + TokenIdentifier, + u64, + BigUint, + >::from(( + TokenIdentifier::from_esdt_bytes(&b""[..]), + 0u64, + BigUint::::from(0u128), + ))]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_sync_accept_funds_multi_transfer(to, token_payments) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn echo_args_async(&mut self) { + let to = bech32::decode(""); + let args = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .echo_args_async(to, args) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_async_accept_funds(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_async_accept_funds(to) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_async_accept_funds_half_payment(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_async_accept_funds_half_payment(to) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_async_accept_funds_with_fees(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + let percentage_fees = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_async_accept_funds_with_fees(to, percentage_fees) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_async_retrieve_funds(&mut self) { + let to = bech32::decode(""); + let token = EgldOrEsdtTokenIdentifier::esdt(&b""[..]); + let token_nonce = 0u64; + let amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_async_retrieve_funds(to, token, token_nonce, amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn send_funds_twice(&mut self) { + let to = bech32::decode(""); + let token_identifier = EgldOrEsdtTokenIdentifier::esdt(&b""[..]); + let amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .send_funds_twice(to, token_identifier, amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn send_async_accept_multi_transfer(&mut self) { + let to = bech32::decode(""); + let token_payments = MultiValueVec::from(vec![MultiValue3::< + TokenIdentifier, + u64, + BigUint, + >::from(( + TokenIdentifier::from_esdt_bytes(&b""[..]), + 0u64, + BigUint::::from(0u128), + ))]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .send_async_accept_multi_transfer(to, token_payments) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn callback_data(&mut self) { + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .callback_data() + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {:?}", result_value.0); + } + + pub async fn callback_data_at_index(&mut self) { + let index = 0u32; + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .callback_data_at_index(index) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } + + pub async fn clear_callback_data(&mut self) { + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .clear_callback_data() + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_transf_exec_accept_funds(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_transf_exec_accept_funds(to) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_transf_execu_accept_funds_with_fees(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + let percentage_fees = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_transf_execu_accept_funds_with_fees(to, percentage_fees) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_transf_exec_accept_funds_twice(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_transf_exec_accept_funds_twice(to) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_transf_exec_accept_funds_return_values(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_transf_exec_accept_funds_return_values(to) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn transf_exec_multi_accept_funds(&mut self) { + let to = bech32::decode(""); + let token_payments = MultiValueVec::from(vec![MultiValue3::< + TokenIdentifier, + u64, + BigUint, + >::from(( + TokenIdentifier::from_esdt_bytes(&b""[..]), + 0u64, + BigUint::::from(0u128), + ))]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .transf_exec_multi_accept_funds(to, token_payments) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn forward_transf_exec_reject_funds_multi_transfer(&mut self) { + let to = bech32::decode(""); + let token_payments = MultiValueVec::from(vec![MultiValue3::< + TokenIdentifier, + u64, + BigUint, + >::from(( + TokenIdentifier::from_esdt_bytes(&b""[..]), + 0u64, + BigUint::::from(0u128), + ))]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .forward_transf_exec_reject_funds_multi_transfer(to, token_payments) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn transf_exec_multi_reject_funds(&mut self) { + let to = bech32::decode(""); + let token_payments = MultiValueVec::from(vec![MultiValue3::< + TokenIdentifier, + u64, + BigUint, + >::from(( + TokenIdentifier::from_esdt_bytes(&b""[..]), + 0u64, + BigUint::::from(0u128), + ))]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .transf_exec_multi_reject_funds(to, token_payments) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn change_owner(&mut self) { + let child_sc_address = bech32::decode(""); + let new_owner = bech32::decode(""); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .change_owner(child_sc_address, new_owner) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn deploy_contract(&mut self) { + let code = ManagedBuffer::new_from_bytes(&b""[..]); + let opt_arg = OptionalValue::Some(ManagedBuffer::new_from_bytes(&b""[..])); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .deploy_contract(code, opt_arg) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn deploy_two_contracts(&mut self) { + let code = ManagedBuffer::new_from_bytes(&b""[..]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .deploy_two_contracts(code) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn deploy_vault_from_source(&mut self) { + let source_address = bech32::decode(""); + let opt_arg = OptionalValue::Some(ManagedBuffer::new_from_bytes(&b""[..])); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .deploy_vault_from_source(source_address, opt_arg) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn upgrade_vault(&mut self) { + let child_sc_address = bech32::decode(""); + let new_code = ManagedBuffer::new_from_bytes(&b""[..]); + let opt_arg = OptionalValue::Some(ManagedBuffer::new_from_bytes(&b""[..])); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .upgrade_vault(child_sc_address, new_code, opt_arg) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn upgrade_vault_from_source(&mut self) { + let child_sc_address = bech32::decode(""); + let source_address = bech32::decode(""); + let opt_arg = OptionalValue::Some(ManagedBuffer::new_from_bytes(&b""[..])); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .upgrade_vault_from_source(child_sc_address, source_address, opt_arg) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn get_fungible_esdt_balance(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .get_fungible_esdt_balance(token_identifier) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } + + pub async fn get_current_nft_nonce(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .get_current_nft_nonce(token_identifier) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } + + pub async fn send_esdt(&mut self) { + let to = bech32::decode(""); + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + let amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .send_esdt(to, token_id, amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn send_esdt_with_fees(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let to = bech32::decode(""); + let percentage_fees = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .send_esdt_with_fees(to, percentage_fees) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn send_esdt_twice(&mut self) { + let to = bech32::decode(""); + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + let amount_first_time = BigUint::::from(0u128); + let amount_second_time = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .send_esdt_twice(to, token_id, amount_first_time, amount_second_time) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn send_esdt_direct_multi_transfer(&mut self) { + let to = bech32::decode(""); + let token_payments = MultiValueVec::from(vec![MultiValue3::< + TokenIdentifier, + u64, + BigUint, + >::from(( + TokenIdentifier::from_esdt_bytes(&b""[..]), + 0u64, + BigUint::::from(0u128), + ))]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .send_esdt_direct_multi_transfer(to, token_payments) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn issue_fungible_token(&mut self) { + let egld_amount = BigUint::::from(0u128); + + let token_display_name = ManagedBuffer::new_from_bytes(&b""[..]); + let token_ticker = ManagedBuffer::new_from_bytes(&b""[..]); + let initial_supply = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .issue_fungible_token(token_display_name, token_ticker, initial_supply) + .egld(egld_amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn local_mint(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .local_mint(token_identifier, amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn local_burn(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .local_burn(token_identifier, amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn get_esdt_local_roles(&mut self) { + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .get_esdt_local_roles(token_id) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } + + pub async fn get_esdt_token_data(&mut self) { + let address = bech32::decode(""); + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .get_esdt_token_data(address, token_id, nonce) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } + + pub async fn is_esdt_frozen(&mut self) { + let address = bech32::decode(""); + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .is_esdt_frozen(address, token_id, nonce) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } + + pub async fn is_esdt_paused(&mut self) { + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .is_esdt_paused(token_id) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } + + pub async fn is_esdt_limited_transfer(&mut self) { + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .is_esdt_limited_transfer(token_id) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } + + pub async fn validate_token_identifier(&mut self) { + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .validate_token_identifier(token_id) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } + + pub async fn sft_issue(&mut self) { + let egld_amount = BigUint::::from(0u128); + + let token_display_name = ManagedBuffer::new_from_bytes(&b""[..]); + let token_ticker = ManagedBuffer::new_from_bytes(&b""[..]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .sft_issue(token_display_name, token_ticker) + .egld(egld_amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn get_nft_balance(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .get_nft_balance(token_identifier, nonce) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } + + pub async fn buy_nft(&mut self) { + let token_id = String::new(); + let token_nonce = 0u64; + let token_amount = BigUint::::from(0u128); + + let nft_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nft_nonce = 0u64; + let nft_amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .buy_nft(nft_id, nft_nonce, nft_amount) + .payment(( + TokenIdentifier::from(token_id.as_str()), + token_nonce, + token_amount, + )) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn nft_issue(&mut self) { + let egld_amount = BigUint::::from(0u128); + + let token_display_name = ManagedBuffer::new_from_bytes(&b""[..]); + let token_ticker = ManagedBuffer::new_from_bytes(&b""[..]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .nft_issue(token_display_name, token_ticker) + .egld(egld_amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn nft_create(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let amount = BigUint::::from(0u128); + let name = ManagedBuffer::new_from_bytes(&b""[..]); + let royalties = BigUint::::from(0u128); + let hash = ManagedBuffer::new_from_bytes(&b""[..]); + let color = Color::default(); + let uri = ManagedBuffer::new_from_bytes(&b""[..]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .nft_create(token_identifier, amount, name, royalties, hash, color, uri) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn nft_create_compact(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let amount = BigUint::::from(0u128); + let color = Color::default(); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .nft_create_compact(token_identifier, amount, color) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn nft_add_uris(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + let uris = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .nft_add_uris(token_identifier, nonce, uris) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn nft_update_attributes(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + let new_attributes = Color::default(); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .nft_update_attributes(token_identifier, nonce, new_attributes) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn nft_decode_complex_attributes(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let amount = BigUint::::from(0u128); + let name = ManagedBuffer::new_from_bytes(&b""[..]); + let royalties = BigUint::::from(0u128); + let hash = ManagedBuffer::new_from_bytes(&b""[..]); + let uri = ManagedBuffer::new_from_bytes(&b""[..]); + let attrs_arg = MultiValue5::< + BigUint, + ManagedBuffer, + TokenIdentifier, + bool, + ManagedBuffer, + >::from(( + BigUint::::from(0u128), + ManagedBuffer::new_from_bytes(&b""[..]), + TokenIdentifier::from_esdt_bytes(&b""[..]), + false, + ManagedBuffer::new_from_bytes(&b""[..]), + )); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .nft_decode_complex_attributes( + token_identifier, + amount, + name, + royalties, + hash, + uri, + attrs_arg, + ) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn nft_add_quantity(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + let amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .nft_add_quantity(token_identifier, nonce, amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn nft_burn(&mut self) { + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + let amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .nft_burn(token_identifier, nonce, amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn transfer_nft_via_async_call(&mut self) { + let to = bech32::decode(""); + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + let amount = BigUint::::from(0u128); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .transfer_nft_via_async_call(to, token_identifier, nonce, amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn transfer_nft_and_execute(&mut self) { + let to = bech32::decode(""); + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + let amount = BigUint::::from(0u128); + let function = ManagedBuffer::new_from_bytes(&b""[..]); + let arguments = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .transfer_nft_and_execute(to, token_identifier, nonce, amount, function, arguments) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn create_and_send(&mut self) { + let to = bech32::decode(""); + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let amount = BigUint::::from(0u128); + let name = ManagedBuffer::new_from_bytes(&b""[..]); + let royalties = BigUint::::from(0u128); + let hash = ManagedBuffer::new_from_bytes(&b""[..]); + let color = Color::default(); + let uri = ManagedBuffer::new_from_bytes(&b""[..]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .create_and_send( + to, + token_identifier, + amount, + name, + royalties, + hash, + color, + uri, + ) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn set_local_roles(&mut self) { + let address = bech32::decode(""); + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let roles = MultiValueVec::::new(); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .set_local_roles(address, token_identifier, roles) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn unset_local_roles(&mut self) { + let address = bech32::decode(""); + let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); + let roles = MultiValueVec::::new(); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .unset_local_roles(address, token_identifier, roles) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn issue_dynamic_token(&mut self) { + let egld_amount = BigUint::::from(0u128); + + let token_display_name = ManagedBuffer::new_from_bytes(&b""[..]); + let token_ticker = ManagedBuffer::new_from_bytes(&b""[..]); + let token_type = EsdtTokenType::DynamicNFT; + let num_decimals = 0u32; + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .issue_dynamic_token(token_display_name, token_ticker, token_type, num_decimals) + .egld(egld_amount) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn change_to_dynamic(&mut self) { + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .change_to_dynamic(token_id) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn update_token(&mut self) { + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .update_token(token_id) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn modify_royalties(&mut self) { + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + let new_royalty = 0u64; + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .modify_royalties(token_id, nonce, new_royalty) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn set_new_uris(&mut self) { + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + let new_uris = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .set_new_uris(token_id, nonce, new_uris) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn modify_creator(&mut self) { + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .modify_creator(token_id, nonce) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn metadata_recreate(&mut self) { + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + let name = ManagedBuffer::new_from_bytes(&b""[..]); + let royalties = 0u64; + let hash = ManagedBuffer::new_from_bytes(&b""[..]); + let new_attributes = Color::default(); + let uris = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .metadata_recreate(token_id, nonce, name, royalties, hash, new_attributes, uris) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn metadata_update(&mut self) { + let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + let nonce = 0u64; + let name = ManagedBuffer::new_from_bytes(&b""[..]); + let royalties = 0u64; + let hash = ManagedBuffer::new_from_bytes(&b""[..]); + let new_attributes = Color::default(); + let uris = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); + + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(30_000_000u64) + .typed(proxy::ForwarderProxy) + .metadata_update(token_id, nonce, name, royalties, hash, new_attributes, uris) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {response:?}"); + } + + pub async fn last_issued_token(&mut self) { + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .last_issued_token() + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } + + pub async fn last_error_message(&mut self) { + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::ForwarderProxy) + .last_error_message() + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result_value:?}"); + } +} diff --git a/contracts/feature-tests/composability/forwarder-interactor/src/interactor_main.rs b/contracts/feature-tests/composability/forwarder-interactor/src/interactor_main.rs new file mode 100644 index 0000000000..cf6bcaa48f --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/src/interactor_main.rs @@ -0,0 +1,7 @@ +use forwarder_interact::forwarder_cli; +use multiversx_sc_snippets::imports::*; + +#[tokio::main] +async fn main() { + forwarder_cli().await; +} diff --git a/contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs b/contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs new file mode 100644 index 0000000000..b27ce77f88 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs @@ -0,0 +1,1375 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct ForwarderProxy; + +impl TxProxyTrait for ForwarderProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = ForwarderProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + ForwarderProxyMethods { wrapped_tx: tx } + } +} + +pub struct ForwarderProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl ForwarderProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl ForwarderProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn send_egld< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_egld") + .argument(&to) + .argument(&amount) + .original_result() + } + + pub fn echo_arguments_sync< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + to: Arg0, + args: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("echo_arguments_sync") + .argument(&to) + .argument(&args) + .original_result() + } + + pub fn echo_arguments_sync_twice< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + to: Arg0, + args: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("echo_arguments_sync_twice") + .argument(&to) + .argument(&args) + .original_result() + } + + pub fn forward_sync_accept_funds< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_sync_accept_funds") + .argument(&to) + .original_result() + } + + pub fn forward_sync_accept_funds_rh_egld< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .raw_call("forward_sync_accept_funds_rh_egld") + .argument(&to) + .original_result() + } + + pub fn forward_sync_accept_funds_rh_single_esdt< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .raw_call("forward_sync_accept_funds_rh_single_esdt") + .argument(&to) + .original_result() + } + + pub fn forward_sync_accept_funds_rh_multi_esdt< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .raw_call("forward_sync_accept_funds_rh_multi_esdt") + .argument(&to) + .original_result() + } + + pub fn forward_sync_accept_funds_with_fees< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + percentage_fees: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_sync_accept_funds_with_fees") + .argument(&to) + .argument(&percentage_fees) + .original_result() + } + + pub fn forward_sync_accept_funds_then_read< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_sync_accept_funds_then_read") + .argument(&to) + .original_result() + } + + pub fn forward_sync_retrieve_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token: Arg1, + token_nonce: Arg2, + amount: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_sync_retrieve_funds") + .argument(&to) + .argument(&token) + .argument(&token_nonce) + .argument(&amount) + .original_result() + } + + pub fn forward_sync_retrieve_funds_with_accept_func< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + to: Arg0, + token: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_sync_retrieve_funds_with_accept_func") + .argument(&to) + .argument(&token) + .argument(&amount) + .original_result() + } + + pub fn accept_funds_func( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept_funds_func") + .original_result() + } + + pub fn forward_sync_accept_funds_multi_transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_sync_accept_funds_multi_transfer") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn echo_args_async< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + to: Arg0, + args: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_args_async") + .argument(&to) + .argument(&args) + .original_result() + } + + pub fn forward_async_accept_funds< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_async_accept_funds") + .argument(&to) + .original_result() + } + + pub fn forward_async_accept_funds_half_payment< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_async_accept_funds_half_payment") + .argument(&to) + .original_result() + } + + pub fn forward_async_accept_funds_with_fees< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + percentage_fees: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_async_accept_funds_with_fees") + .argument(&to) + .argument(&percentage_fees) + .original_result() + } + + pub fn forward_async_retrieve_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token: Arg1, + token_nonce: Arg2, + amount: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_async_retrieve_funds") + .argument(&to) + .argument(&token) + .argument(&token_nonce) + .argument(&amount) + .original_result() + } + + pub fn send_funds_twice< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + to: Arg0, + token_identifier: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_funds_twice") + .argument(&to) + .argument(&token_identifier) + .argument(&amount) + .original_result() + } + + pub fn send_async_accept_multi_transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_async_accept_multi_transfer") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn callback_data( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("callback_data") + .original_result() + } + + pub fn callback_data_at_index< + Arg0: ProxyArg, + >( + self, + index: Arg0, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier, u64, BigUint, MultiValueManagedVec>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("callback_data_at_index") + .argument(&index) + .original_result() + } + + pub fn clear_callback_data( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("clear_callback_data") + .original_result() + } + + pub fn forward_transf_exec_accept_funds< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_transf_exec_accept_funds") + .argument(&to) + .original_result() + } + + pub fn forward_transf_execu_accept_funds_with_fees< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + percentage_fees: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_transf_execu_accept_funds_with_fees") + .argument(&to) + .argument(&percentage_fees) + .original_result() + } + + pub fn forward_transf_exec_accept_funds_twice< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_transf_exec_accept_funds_twice") + .argument(&to) + .original_result() + } + + /// Test that the default gas provided to the transfer_execute call + /// leaves enough in the transaction for finish to happen. + pub fn forward_transf_exec_accept_funds_return_values< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("forward_transf_exec_accept_funds_return_values") + .argument(&to) + .original_result() + } + + pub fn transf_exec_multi_accept_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transf_exec_multi_accept_funds") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn forward_transf_exec_reject_funds_multi_transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_transf_exec_reject_funds_multi_transfer") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn transf_exec_multi_reject_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transf_exec_multi_reject_funds") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn change_owner< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + child_sc_address: Arg0, + new_owner: Arg1, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("changeOwnerAddress") + .argument(&child_sc_address) + .argument(&new_owner) + .original_result() + } + + pub fn deploy_contract< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + code: Arg0, + opt_arg: Arg1, + ) -> TxTypedCall, OptionalValue>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("deploy_contract") + .argument(&code) + .argument(&opt_arg) + .original_result() + } + + pub fn deploy_two_contracts< + Arg0: ProxyArg>, + >( + self, + code: Arg0, + ) -> TxTypedCall, ManagedAddress>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("deploy_two_contracts") + .argument(&code) + .original_result() + } + + pub fn deploy_vault_from_source< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + source_address: Arg0, + opt_arg: Arg1, + ) -> TxTypedCall, OptionalValue>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("deploy_vault_from_source") + .argument(&source_address) + .argument(&opt_arg) + .original_result() + } + + pub fn upgrade_vault< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + >( + self, + child_sc_address: Arg0, + new_code: Arg1, + opt_arg: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("upgradeVault") + .argument(&child_sc_address) + .argument(&new_code) + .argument(&opt_arg) + .original_result() + } + + pub fn upgrade_vault_from_source< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + >( + self, + child_sc_address: Arg0, + source_address: Arg1, + opt_arg: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("upgrade_vault_from_source") + .argument(&child_sc_address) + .argument(&source_address) + .argument(&opt_arg) + .original_result() + } + + pub fn get_fungible_esdt_balance< + Arg0: ProxyArg>, + >( + self, + token_identifier: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getFungibleEsdtBalance") + .argument(&token_identifier) + .original_result() + } + + pub fn get_current_nft_nonce< + Arg0: ProxyArg>, + >( + self, + token_identifier: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getCurrentNftNonce") + .argument(&token_identifier) + .original_result() + } + + pub fn send_esdt< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + to: Arg0, + token_id: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_esdt") + .argument(&to) + .argument(&token_id) + .argument(&amount) + .original_result() + } + + pub fn send_esdt_with_fees< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + percentage_fees: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("send_esdt_with_fees") + .argument(&to) + .argument(&percentage_fees) + .original_result() + } + + pub fn send_esdt_twice< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token_id: Arg1, + amount_first_time: Arg2, + amount_second_time: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_esdt_twice") + .argument(&to) + .argument(&token_id) + .argument(&amount_first_time) + .argument(&amount_second_time) + .original_result() + } + + pub fn send_esdt_direct_multi_transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_esdt_direct_multi_transfer") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn issue_fungible_token< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + initial_supply: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("issue_fungible_token") + .argument(&token_display_name) + .argument(&token_ticker) + .argument(&initial_supply) + .original_result() + } + + pub fn local_mint< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("local_mint") + .argument(&token_identifier) + .argument(&amount) + .original_result() + } + + pub fn local_burn< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("local_burn") + .argument(&token_identifier) + .argument(&amount) + .original_result() + } + + pub fn get_esdt_local_roles< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("get_esdt_local_roles") + .argument(&token_id) + .original_result() + } + + pub fn get_esdt_token_data< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + address: Arg0, + token_id: Arg1, + nonce: Arg2, + ) -> TxTypedCall, bool, ManagedBuffer, ManagedBuffer, ManagedBuffer, ManagedAddress, BigUint, ManagedVec>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("get_esdt_token_data") + .argument(&address) + .argument(&token_id) + .argument(&nonce) + .original_result() + } + + pub fn is_esdt_frozen< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + address: Arg0, + token_id: Arg1, + nonce: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("is_esdt_frozen") + .argument(&address) + .argument(&token_id) + .argument(&nonce) + .original_result() + } + + pub fn is_esdt_paused< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("is_esdt_paused") + .argument(&token_id) + .original_result() + } + + pub fn is_esdt_limited_transfer< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("is_esdt_limited_transfer") + .argument(&token_id) + .original_result() + } + + pub fn validate_token_identifier< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("validate_token_identifier") + .argument(&token_id) + .original_result() + } + + pub fn sft_issue< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("sft_issue") + .argument(&token_display_name) + .argument(&token_ticker) + .original_result() + } + + pub fn get_nft_balance< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + token_identifier: Arg0, + nonce: Arg1, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("get_nft_balance") + .argument(&token_identifier) + .argument(&nonce) + .original_result() + } + + pub fn buy_nft< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + nft_id: Arg0, + nft_nonce: Arg1, + nft_amount: Arg2, + ) -> TxTypedCall> { + self.wrapped_tx + .raw_call("buy_nft") + .argument(&nft_id) + .argument(&nft_nonce) + .argument(&nft_amount) + .original_result() + } + + pub fn nft_issue< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("nft_issue") + .argument(&token_display_name) + .argument(&token_ticker) + .original_result() + } + + pub fn nft_create< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + Arg5: ProxyArg, + Arg6: ProxyArg>, + >( + self, + token_identifier: Arg0, + amount: Arg1, + name: Arg2, + royalties: Arg3, + hash: Arg4, + color: Arg5, + uri: Arg6, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_create") + .argument(&token_identifier) + .argument(&amount) + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&color) + .argument(&uri) + .original_result() + } + + pub fn nft_create_compact< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + token_identifier: Arg0, + amount: Arg1, + color: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_create_compact") + .argument(&token_identifier) + .argument(&amount) + .argument(&color) + .original_result() + } + + pub fn nft_add_uris< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>>, + >( + self, + token_identifier: Arg0, + nonce: Arg1, + uris: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_add_uris") + .argument(&token_identifier) + .argument(&nonce) + .argument(&uris) + .original_result() + } + + pub fn nft_update_attributes< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg, + >( + self, + token_identifier: Arg0, + nonce: Arg1, + new_attributes: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_update_attributes") + .argument(&token_identifier) + .argument(&nonce) + .argument(&new_attributes) + .original_result() + } + + pub fn nft_decode_complex_attributes< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + Arg5: ProxyArg>, + Arg6: ProxyArg, ManagedBuffer, TokenIdentifier, bool, ManagedBuffer>>, + >( + self, + token_identifier: Arg0, + amount: Arg1, + name: Arg2, + royalties: Arg3, + hash: Arg4, + uri: Arg5, + attrs_arg: Arg6, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_decode_complex_attributes") + .argument(&token_identifier) + .argument(&amount) + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&uri) + .argument(&attrs_arg) + .original_result() + } + + pub fn nft_add_quantity< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + token_identifier: Arg0, + nonce: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_add_quantity") + .argument(&token_identifier) + .argument(&nonce) + .argument(&amount) + .original_result() + } + + pub fn nft_burn< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + token_identifier: Arg0, + nonce: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_burn") + .argument(&token_identifier) + .argument(&nonce) + .argument(&amount) + .original_result() + } + + pub fn transfer_nft_via_async_call< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token_identifier: Arg1, + nonce: Arg2, + amount: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transfer_nft_via_async_call") + .argument(&to) + .argument(&token_identifier) + .argument(&nonce) + .argument(&amount) + .original_result() + } + + pub fn transfer_nft_and_execute< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + Arg5: ProxyArg>>, + >( + self, + to: Arg0, + token_identifier: Arg1, + nonce: Arg2, + amount: Arg3, + function: Arg4, + arguments: Arg5, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transfer_nft_and_execute") + .argument(&to) + .argument(&token_identifier) + .argument(&nonce) + .argument(&amount) + .argument(&function) + .argument(&arguments) + .original_result() + } + + pub fn create_and_send< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + Arg5: ProxyArg>, + Arg6: ProxyArg, + Arg7: ProxyArg>, + >( + self, + to: Arg0, + token_identifier: Arg1, + amount: Arg2, + name: Arg3, + royalties: Arg4, + hash: Arg5, + color: Arg6, + uri: Arg7, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("create_and_send") + .argument(&to) + .argument(&token_identifier) + .argument(&amount) + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&color) + .argument(&uri) + .original_result() + } + + pub fn set_local_roles< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + address: Arg0, + token_identifier: Arg1, + roles: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("setLocalRoles") + .argument(&address) + .argument(&token_identifier) + .argument(&roles) + .original_result() + } + + pub fn unset_local_roles< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + address: Arg0, + token_identifier: Arg1, + roles: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("unsetLocalRoles") + .argument(&address) + .argument(&token_identifier) + .argument(&roles) + .original_result() + } + + pub fn issue_dynamic_token< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + token_type: Arg2, + num_decimals: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("issue_dynamic_token") + .argument(&token_display_name) + .argument(&token_ticker) + .argument(&token_type) + .argument(&num_decimals) + .original_result() + } + + pub fn change_to_dynamic< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("change_to_dynamic") + .argument(&token_id) + .original_result() + } + + pub fn update_token< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("update_token") + .argument(&token_id) + .original_result() + } + + pub fn modify_royalties< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg, + >( + self, + token_id: Arg0, + nonce: Arg1, + new_royalty: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("modify_royalties") + .argument(&token_id) + .argument(&nonce) + .argument(&new_royalty) + .original_result() + } + + pub fn set_new_uris< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>>, + >( + self, + token_id: Arg0, + nonce: Arg1, + new_uris: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("set_new_uris") + .argument(&token_id) + .argument(&nonce) + .argument(&new_uris) + .original_result() + } + + pub fn modify_creator< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + token_id: Arg0, + nonce: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("modify_creator") + .argument(&token_id) + .argument(&nonce) + .original_result() + } + + pub fn metadata_recreate< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + Arg3: ProxyArg, + Arg4: ProxyArg>, + Arg5: ProxyArg, + Arg6: ProxyArg>>, + >( + self, + token_id: Arg0, + nonce: Arg1, + name: Arg2, + royalties: Arg3, + hash: Arg4, + new_attributes: Arg5, + uris: Arg6, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("metadata_recreate") + .argument(&token_id) + .argument(&nonce) + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&new_attributes) + .argument(&uris) + .original_result() + } + + pub fn metadata_update< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + Arg3: ProxyArg, + Arg4: ProxyArg>, + Arg5: ProxyArg, + Arg6: ProxyArg>>, + >( + self, + token_id: Arg0, + nonce: Arg1, + name: Arg2, + royalties: Arg3, + hash: Arg4, + new_attributes: Arg5, + uris: Arg6, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("metadata_update") + .argument(&token_id) + .argument(&nonce) + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&new_attributes) + .argument(&uris) + .original_result() + } + + pub fn last_issued_token( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("lastIssuedToken") + .original_result() + } + + pub fn last_error_message( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("lastErrorMessage") + .original_result() + } +} + +#[type_abi] +#[derive(TopEncode, TopDecode, Debug)] +pub struct CallbackData +where + Api: ManagedTypeApi, +{ + pub callback_name: ManagedBuffer, + pub token_identifier: EgldOrEsdtTokenIdentifier, + pub token_nonce: u64, + pub token_amount: BigUint, + pub args: ManagedVec>, +} + +#[type_abi] +#[derive(TopEncode, TopDecode, Clone, Copy, PartialEq, Debug, Default)] +pub struct Color { + pub r: u8, + pub g: u8, + pub b: u8, +} diff --git a/contracts/feature-tests/composability/forwarder-interactor/state.toml b/contracts/feature-tests/composability/forwarder-interactor/state.toml new file mode 100644 index 0000000000..0bf61e6358 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/state.toml @@ -0,0 +1 @@ +contract_address = "erd1qqqqqqqqqqqqqpgqcr2nq237tg5vr3ezjvr750spkmtsjstjd8ssfp6eun" diff --git a/contracts/feature-tests/composability/forwarder-interactor/tests/interact_cs_tests.rs b/contracts/feature-tests/composability/forwarder-interactor/tests/interact_cs_tests.rs new file mode 100644 index 0000000000..b85fc01bf3 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/tests/interact_cs_tests.rs @@ -0,0 +1,15 @@ +use forwarder_interact::ContractInteract; +use multiversx_sc_snippets::imports::*; + +// Simple deploy test that runs using the chain simulator configuration. +// In order for this test to work, make sure that the `config.toml` file contains the chain simulator config (or choose it manually) +// The chain simulator should already be installed and running before attempting to run this test. +// The chain-simulator-tests feature should be present in Cargo.toml. +// Can be run with `sc-meta test -c`. +#[tokio::test] +#[cfg_attr(not(feature = "chain-simulator-tests"), ignore)] +async fn deploy_test_forwarder_cs() { + let mut interactor = ContractInteract::new().await; + + interactor.deploy().await; +} diff --git a/contracts/feature-tests/composability/forwarder-interactor/tests/interact_tests.rs b/contracts/feature-tests/composability/forwarder-interactor/tests/interact_tests.rs new file mode 100644 index 0000000000..2005f0176f --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/tests/interact_tests.rs @@ -0,0 +1,13 @@ +use forwarder_interact::ContractInteract; +use multiversx_sc_snippets::imports::*; + +// Simple deploy test that runs on the real blockchain configuration. +// In order for this test to work, make sure that the `config.toml` file contains the real blockchain config (or choose it manually) +// Can be run with `sc-meta test`. +#[tokio::test] +#[ignore = "run on demand, relies on real blockchain state"] +async fn deploy_test_forwarder() { + let mut interactor = ContractInteract::new().await; + + interactor.deploy().await; +} diff --git a/contracts/feature-tests/composability/forwarder/sc-config.toml b/contracts/feature-tests/composability/forwarder/sc-config.toml index b78f0086a5..5974cd2dbf 100644 --- a/contracts/feature-tests/composability/forwarder/sc-config.toml +++ b/contracts/feature-tests/composability/forwarder/sc-config.toml @@ -1,2 +1,6 @@ [[proxy]] path = "src/forwarder_proxy.rs" + +[[proxy]] +path = "../forwarder-interactor/src/proxy.rs" + diff --git a/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs b/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs index 964df0bf23..b27ce77f88 100644 --- a/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs +++ b/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs @@ -1354,7 +1354,7 @@ where } #[type_abi] -#[derive(TopEncode, TopDecode)] +#[derive(TopEncode, TopDecode, Debug)] pub struct CallbackData where Api: ManagedTypeApi, @@ -1367,7 +1367,7 @@ where } #[type_abi] -#[derive(TopEncode, TopDecode, Clone, Copy, PartialEq, Debug)] +#[derive(TopEncode, TopDecode, Clone, Copy, PartialEq, Debug, Default)] pub struct Color { pub r: u8, pub g: u8, 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 5492a45a10..463cd26465 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_call_async.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_async.rs @@ -4,7 +4,7 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); #[type_abi] -#[derive(TopEncode, TopDecode)] +#[derive(TopEncode, TopDecode, Debug)] pub struct CallbackData { callback_name: ManagedBuffer, token_identifier: EgldOrEsdtTokenIdentifier, diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs b/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs index 5358397df9..53f01ec5ea 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs @@ -5,7 +5,7 @@ use super::fwd_storage; // used as mock attributes for NFTs #[type_abi] -#[derive(TopEncode, TopDecode, Clone, Copy, PartialEq, Debug)] +#[derive(TopEncode, TopDecode, Clone, Copy, PartialEq, Debug, Default)] pub struct Color { pub r: u8, pub g: u8, @@ -13,7 +13,7 @@ pub struct Color { } #[type_abi] -#[derive(TopEncode, TopDecode, PartialEq, Eq, Clone)] +#[derive(TopEncode, TopDecode, PartialEq, Eq, Clone, Debug)] pub struct ComplexAttributes { pub biguint: BigUint, pub vec_u8: ManagedBuffer, From e3888bdb321da56c8a77a8cb25717c97bff144c6 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Mon, 9 Dec 2024 17:23:16 +0100 Subject: [PATCH 078/133] interactor scenarios, mandos gen --- .../forwarder_builtin_scenario.scen.json | 312 ++++++++++++ ...arder_change_to_dynamic_scenario.scen.json | 173 +++++++ .../forwarder_deploy_scenario.scen.json | 28 ++ ...orwarder_modify_creator_scenario.scen.json | 153 ++++++ .../forwarder_update_token_scenario.scen.json | 87 ++++ .../forwarder-interactor/src/config.rs | 6 + .../forwarder-interactor/src/interact.rs | 445 ++++++++++++------ .../forwarder-interactor/src/proxy.rs | 21 + .../forwarder-interactor/state.toml | 2 +- .../tests/interact_cs_tests.rs | 4 +- .../tests/interact_tests.rs | 332 ++++++++++++- .../forwarder/src/forwarder_proxy.rs | 21 + .../forwarder/src/fwd_dynamic.rs | 29 +- .../composability/forwarder/wasm/src/lib.rs | 5 +- 14 files changed, 1472 insertions(+), 146 deletions(-) create mode 100644 contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_builtin_scenario.scen.json create mode 100644 contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_change_to_dynamic_scenario.scen.json create mode 100644 contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_deploy_scenario.scen.json create mode 100644 contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_modify_creator_scenario.scen.json create mode 100644 contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_update_token_scenario.scen.json diff --git a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_builtin_scenario.scen.json b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_builtin_scenario.scen.json new file mode 100644 index 0000000000..7bdf624811 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_builtin_scenario.scen.json @@ -0,0 +1,312 @@ +{ + "steps": [ + { + "step": "setState", + "newAddresses": [ + { + "creatorAddress": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "creatorNonce": "11899", + "newAddress": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv" + } + ] + }, + { + "step": "scDeploy", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "contractCode": "mxsc:../../forwarder/output/forwarder.mxsc.json", + "arguments": [], + "gasLimit": "300000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-d49726" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "egldValue": "50000000000000000", + "function": "issue_dynamic_token", + "arguments": [ + "0x544553544e4654", + "0x54455354", + "0x04", + "0x" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-38e345" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "egldValue": "50000000000000000", + "function": "issue_dynamic_token", + "arguments": [ + "0x544553544e4654", + "0x54455354", + "0x05", + "0x" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-f781d6" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "egldValue": "50000000000000000", + "function": "issue_dynamic_token", + "arguments": [ + "0x544553544e4654", + "0x54455354", + "0x06", + "0x12" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-2b25f7" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "egldValue": "50000000000000000", + "function": "issue_token_all_roles", + "arguments": [ + "0x544553544e4654", + "0x54455354", + "0x06", + "0x" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-d0c358" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "egldValue": "50000000000000000", + "function": "issue_token_all_roles", + "arguments": [ + "0x544553544e4654", + "0x54455354", + "0x05", + "0x" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-712a3f" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "egldValue": "50000000000000000", + "function": "issue_token_all_roles", + "arguments": [ + "0x544553544e4654", + "0x54455354", + "0x04", + "0x" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scQuery", + "id": "", + "tx": { + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "function": "lastIssuedToken", + "arguments": [] + }, + "expect": { + "out": [ + "0x544553542d373132613366" + ], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "function": "nft_create", + "arguments": [ + "0x544553542d373132613366", + "0x01", + "0x6d794e4654", + "0x1e", + "0x", + "0x010205", + "0x73616d706c655f757269" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [ + "0x01" + ], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "function": "modify_royalties", + "arguments": [ + "0x544553542d373132613366", + "0x01", + "0x14" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "function": "set_new_uris", + "arguments": [ + "0x544553542d373132613366", + "0x01", + "0x7468697369616e7572692e636f6d" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "function": "metadata_update", + "arguments": [ + "0x544553542d373132613366", + "0x01", + "0x544553544e4654", + "0x1e", + "0x6e65775f68617368", + "0x060708" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqwzty5wrdva7ymtwfrkj23ysdaauxx6j4d8sskh9qsv", + "function": "metadata_recreate", + "arguments": [ + "0x544553542d373132613366", + "0x01", + "0x544553544e4654", + "0x1e", + "0x6e65775f686173685f726563726561746564", + "0x080808" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + } + ] +} diff --git a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_change_to_dynamic_scenario.scen.json b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_change_to_dynamic_scenario.scen.json new file mode 100644 index 0000000000..ba64c01c26 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_change_to_dynamic_scenario.scen.json @@ -0,0 +1,173 @@ +{ + "steps": [ + { + "step": "setState", + "newAddresses": [ + { + "creatorAddress": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "creatorNonce": "11911", + "newAddress": "bech32:erd1qqqqqqqqqqqqqpgqkwwmszeln3cjlxewv0a3uwgxf2ver22rd8ssdgezus" + } + ] + }, + { + "step": "scDeploy", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "contractCode": "mxsc:../../forwarder/output/forwarder.mxsc.json", + "arguments": [], + "gasLimit": "300000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-34ddd9" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqkwwmszeln3cjlxewv0a3uwgxf2ver22rd8ssdgezus", + "egldValue": "50000000000000000", + "function": "issue_token_all_roles", + "arguments": [ + "0x544553544e4654", + "0x54455354", + "0x01", + "0x" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-a0503d" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqkwwmszeln3cjlxewv0a3uwgxf2ver22rd8ssdgezus", + "egldValue": "50000000000000000", + "function": "issue_token_all_roles", + "arguments": [ + "0x544553544e4654", + "0x54455354", + "0x03", + "0x12" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scQuery", + "id": "", + "tx": { + "to": "bech32:erd1qqqqqqqqqqqqqpgqkwwmszeln3cjlxewv0a3uwgxf2ver22rd8ssdgezus", + "function": "lastIssuedToken", + "arguments": [] + }, + "expect": { + "out": [ + "0x544553542d613035303364" + ], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqkwwmszeln3cjlxewv0a3uwgxf2ver22rd8ssdgezus", + "function": "change_to_dynamic", + "arguments": [ + "0x544553542d613035303364" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-45f8e0" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqkwwmszeln3cjlxewv0a3uwgxf2ver22rd8ssdgezus", + "egldValue": "50000000000000000", + "function": "issue_token_all_roles", + "arguments": [ + "0x544553544e4654", + "0x54455354", + "0x02", + "0x12" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scQuery", + "id": "", + "tx": { + "to": "bech32:erd1qqqqqqqqqqqqqpgqkwwmszeln3cjlxewv0a3uwgxf2ver22rd8ssdgezus", + "function": "lastIssuedToken", + "arguments": [] + }, + "expect": { + "out": [ + "0x544553542d343566386530" + ], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqkwwmszeln3cjlxewv0a3uwgxf2ver22rd8ssdgezus", + "function": "change_to_dynamic", + "arguments": [ + "0x544553542d343566386530" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + } + ] +} diff --git a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_deploy_scenario.scen.json b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_deploy_scenario.scen.json new file mode 100644 index 0000000000..09281ed0f3 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_deploy_scenario.scen.json @@ -0,0 +1,28 @@ +{ + "steps": [ + { + "step": "setState", + "newAddresses": [ + { + "creatorAddress": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "creatorNonce": "11920", + "newAddress": "bech32:erd1qqqqqqqqqqqqqpgq3tjap9t5nnat46nwdz6mtyy60na7vptnd8ss7r0jp8" + } + ] + }, + { + "step": "scDeploy", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "contractCode": "mxsc:../../forwarder/output/forwarder.mxsc.json", + "arguments": [], + "gasLimit": "300000000" + }, + "expect": { + "out": [], + "status": "0" + } + } + ] +} diff --git a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_modify_creator_scenario.scen.json b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_modify_creator_scenario.scen.json new file mode 100644 index 0000000000..fe3e78431e --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_modify_creator_scenario.scen.json @@ -0,0 +1,153 @@ +{ + "steps": [ + { + "step": "setState", + "newAddresses": [ + { + "creatorAddress": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "creatorNonce": "11928", + "newAddress": "bech32:erd1qqqqqqqqqqqqqpgqm6d7cp70y7ft6xe78f7np9agdm7vpce6d8sskuuxnu" + } + ] + }, + { + "step": "scDeploy", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "contractCode": "mxsc:../../forwarder/output/forwarder.mxsc.json", + "arguments": [], + "gasLimit": "300000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-d3c4e5" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "egldValue": "50000000000000000", + "function": "registerDynamic", + "arguments": [ + "0x544553544e4654", + "0x54455354", + "0x4e4654" + ], + "gasLimit": "100000000" + }, + "expect": { + "out": [ + "0x544553542d643363346535" + ], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "function": "setSpecialRole", + "arguments": [ + "0x544553542d643363346535", + "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "0x45534454526f6c654e4654437265617465" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "function": "ESDTNFTCreate", + "arguments": [ + "0x544553542d643363346535", + "0x01", + "0x6d794e4654", + "0x1e", + "0x", + "0x010203", + "0x" + ], + "gasLimit": "100000000" + }, + "expect": { + "out": [ + "0x01" + ], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "function": "setSpecialRole", + "arguments": [ + "0x544553542d643363346535", + "0x00000000000000000500de9bec07cf2792bd1b3e3a7d3097a86efcc0e33a69e1", + "0x45534454526f6c654d6f6469667943726561746f72" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "transfer", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqm6d7cp70y7ft6xe78f7np9agdm7vpce6d8sskuuxnu", + "esdtValue": [ + { + "tokenIdentifier": "0x544553542d643363346535", + "nonce": "1", + "value": "1" + } + ], + "gasLimit": "5,000,000" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqm6d7cp70y7ft6xe78f7np9agdm7vpce6d8sskuuxnu", + "function": "modify_creator", + "arguments": [ + "0x544553542d643363346535", + "0x01" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + } + ] +} \ No newline at end of file diff --git a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_update_token_scenario.scen.json b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_update_token_scenario.scen.json new file mode 100644 index 0000000000..4ddfaab647 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_update_token_scenario.scen.json @@ -0,0 +1,87 @@ +{ + "steps": [ + { + "step": "setState", + "newAddresses": [ + { + "creatorAddress": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "creatorNonce": "11917", + "newAddress": "bech32:erd1qqqqqqqqqqqqqpgqyjhk2jz7rmv7hrdcnlzwtr3pcd69hw7nd8ssjv0ryz" + } + ] + }, + { + "step": "scDeploy", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "contractCode": "mxsc:../../forwarder/output/forwarder.mxsc.json", + "arguments": [], + "gasLimit": "300000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "setState", + "newTokenIdentifiers": [ + "TEST-4ec598" + ] + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqyjhk2jz7rmv7hrdcnlzwtr3pcd69hw7nd8ssjv0ryz", + "egldValue": "50000000000000000", + "function": "issue_token_all_roles", + "arguments": [ + "0x544553544e4654", + "0x54455354", + "0x01", + "0x" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scQuery", + "id": "", + "tx": { + "to": "bech32:erd1qqqqqqqqqqqqqpgqyjhk2jz7rmv7hrdcnlzwtr3pcd69hw7nd8ssjv0ryz", + "function": "lastIssuedToken", + "arguments": [] + }, + "expect": { + "out": [ + "0x544553542d346563353938" + ], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "to": "bech32:erd1qqqqqqqqqqqqqpgqyjhk2jz7rmv7hrdcnlzwtr3pcd69hw7nd8ssjv0ryz", + "function": "update_token", + "arguments": [ + "0x544553542d346563353938" + ], + "gasLimit": "80000000" + }, + "expect": { + "out": [], + "status": "0" + } + } + ] +} \ No newline at end of file diff --git a/contracts/feature-tests/composability/forwarder-interactor/src/config.rs b/contracts/feature-tests/composability/forwarder-interactor/src/config.rs index 2d072b4bfb..4c4f034bb4 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/src/config.rs +++ b/contracts/feature-tests/composability/forwarder-interactor/src/config.rs @@ -20,6 +20,12 @@ pub struct Config { pub chain_type: ChainType, } +impl Default for Config { + fn default() -> Self { + Self::new() + } +} + impl Config { // Deserializes config from file pub fn new() -> Self { diff --git a/contracts/feature-tests/composability/forwarder-interactor/src/interact.rs b/contracts/feature-tests/composability/forwarder-interactor/src/interact.rs index b4ed599a3e..bce4d4798c 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/src/interact.rs +++ b/contracts/feature-tests/composability/forwarder-interactor/src/interact.rs @@ -3,9 +3,9 @@ mod config; mod proxy; -use config::Config; +pub use config::Config; use multiversx_sc_snippets::imports::*; -use proxy::Color; +pub use proxy::Color; use serde::{Deserialize, Serialize}; use std::{ io::{Read, Write}, @@ -13,6 +13,16 @@ use std::{ }; const STATE_FILE: &str = "state.toml"; +pub const FORWARDER_DEPLOY_INTERACTOR_TRACE_PATH: &str = + "scenarios/forwarder_deploy_scenario.scen.json"; +pub const FORWARDER_BUILTIN_INTERACTOR_TRACE_PATH: &str = + "scenarios/forwarder_builtin_scenario.scen.json"; +pub const FORWARDER_CHANGE_TO_DYNAMIC_INTERACTOR_TRACE_PATH: &str = + "scenarios/forwarder_change_to_dynamic_scenario.scen.json"; +pub const FORWARDER_UPDATE_TOKEN_INTERACTOR_TRACE_PATH: &str = + "scenarios/forwarder_update_token_scenario.scen.json"; +pub const FORWARDER_MODIFY_CREATOR_INTERACTOR_TRACE_PATH: &str = + "scenarios/forwarder_modify_creator_scenario.scen.json"; pub async fn forwarder_cli() { env_logger::init(); @@ -20,7 +30,7 @@ pub async fn forwarder_cli() { let mut args = std::env::args(); let _ = args.next(); let cmd = args.next().expect("at least one argument required"); - let mut interact = ContractInteract::new().await; + let mut interact = ContractInteract::new(Config::new(), None).await; match cmd.as_str() { "deploy" => interact.deploy().await, "send_egld" => interact.send_egld().await, @@ -108,7 +118,7 @@ pub async fn forwarder_cli() { "get_nft_balance" => interact.get_nft_balance().await, "buy_nft" => interact.buy_nft().await, "nft_issue" => interact.nft_issue().await, - "nft_create" => interact.nft_create().await, + // "nft_create" => interact.nft_create().await, "nft_create_compact" => interact.nft_create_compact().await, "nft_add_uris" => interact.nft_add_uris().await, "nft_update_attributes" => interact.nft_update_attributes().await, @@ -120,15 +130,15 @@ pub async fn forwarder_cli() { "create_and_send" => interact.create_and_send().await, "setLocalRoles" => interact.set_local_roles().await, "unsetLocalRoles" => interact.unset_local_roles().await, - "issue_dynamic_token" => interact.issue_dynamic_token().await, - "change_to_dynamic" => interact.change_to_dynamic().await, - "update_token" => interact.update_token().await, - "modify_royalties" => interact.modify_royalties().await, - "set_new_uris" => interact.set_new_uris().await, - "modify_creator" => interact.modify_creator().await, - "metadata_recreate" => interact.metadata_recreate().await, - "metadata_update" => interact.metadata_update().await, - "lastIssuedToken" => interact.last_issued_token().await, + // "issue_dynamic_token" => interact.issue_dynamic_token().await, + // "change_to_dynamic" => interact.change_to_dynamic().await, + // "update_token" => interact.update_token().await, + // "modify_royalties" => interact.modify_royalties().await, + // "set_new_uris" => interact.set_new_uris().await, + // "modify_creator" => interact.modify_creator().await, + // "metadata_recreate" => interact.metadata_recreate().await, + // "metadata_update" => interact.metadata_update().await, + // "lastIssuedToken" => interact.last_issued_token().await, "lastErrorMessage" => interact.last_error_message().await, _ => panic!("unknown command: {}", &cmd), } @@ -176,18 +186,21 @@ impl Drop for State { pub struct ContractInteract { interactor: Interactor, - wallet_address: Address, + pub wallet_address: Address, contract_code: BytesValue, - state: State, + pub state: State, } impl ContractInteract { - pub async fn new() -> Self { - let config = Config::new(); + pub async fn new(config: Config, trace_path: Option<&str>) -> Self { let mut interactor = Interactor::new(config.gateway_uri()) .await .use_chain_simulator(config.use_chain_simulator()); + if let Some(path) = trace_path { + interactor = interactor.with_tracer(path).await; + } + interactor.set_current_dir_from_workspace("forwarder-interactor"); let wallet_address = interactor.register_wallet(test_wallets::alice()).await; @@ -237,7 +250,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .send_egld(to, amount) .returns(ReturnsResultUnmanaged) @@ -260,7 +273,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .echo_arguments_sync(to, args) .payment(( @@ -288,7 +301,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .echo_arguments_sync_twice(to, args) .payment(( @@ -315,7 +328,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_sync_accept_funds(to) .payment(( @@ -340,7 +353,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_sync_accept_funds_rh_egld(to) .egld(egld_amount) @@ -363,7 +376,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_sync_accept_funds_rh_single_esdt(to) .payment(( @@ -390,7 +403,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_sync_accept_funds_rh_multi_esdt(to) .payment(( @@ -418,7 +431,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_sync_accept_funds_with_fees(to, percentage_fees) .payment(( @@ -445,7 +458,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_sync_accept_funds_then_read(to) .payment(( @@ -471,7 +484,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_sync_retrieve_funds(to, token, token_nonce, amount) .returns(ReturnsResultUnmanaged) @@ -495,7 +508,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_sync_retrieve_funds_with_accept_func(to, token, amount) .payment(( @@ -520,7 +533,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .accept_funds_func() .payment(( @@ -552,7 +565,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_sync_accept_funds_multi_transfer(to, token_payments) .returns(ReturnsResultUnmanaged) @@ -571,7 +584,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .echo_args_async(to, args) .returns(ReturnsResultUnmanaged) @@ -593,7 +606,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_async_accept_funds(to) .payment(( @@ -620,7 +633,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_async_accept_funds_half_payment(to) .payment(( @@ -648,7 +661,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_async_accept_funds_with_fees(to, percentage_fees) .payment(( @@ -674,7 +687,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_async_retrieve_funds(to, token, token_nonce, amount) .returns(ReturnsResultUnmanaged) @@ -694,7 +707,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .send_funds_twice(to, token_identifier, amount) .returns(ReturnsResultUnmanaged) @@ -721,7 +734,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .send_async_accept_multi_transfer(to, token_payments) .returns(ReturnsResultUnmanaged) @@ -767,7 +780,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .clear_callback_data() .returns(ReturnsResultUnmanaged) @@ -789,7 +802,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_transf_exec_accept_funds(to) .payment(( @@ -817,7 +830,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_transf_execu_accept_funds_with_fees(to, percentage_fees) .payment(( @@ -844,7 +857,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_transf_exec_accept_funds_twice(to) .payment(( @@ -871,7 +884,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_transf_exec_accept_funds_return_values(to) .payment(( @@ -903,7 +916,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .transf_exec_multi_accept_funds(to, token_payments) .returns(ReturnsResultUnmanaged) @@ -930,7 +943,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .forward_transf_exec_reject_funds_multi_transfer(to, token_payments) .returns(ReturnsResultUnmanaged) @@ -957,7 +970,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .transf_exec_multi_reject_funds(to, token_payments) .returns(ReturnsResultUnmanaged) @@ -976,7 +989,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .change_owner(child_sc_address, new_owner) .returns(ReturnsResultUnmanaged) @@ -995,7 +1008,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .deploy_contract(code, opt_arg) .returns(ReturnsResultUnmanaged) @@ -1013,7 +1026,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .deploy_two_contracts(code) .returns(ReturnsResultUnmanaged) @@ -1032,7 +1045,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .deploy_vault_from_source(source_address, opt_arg) .returns(ReturnsResultUnmanaged) @@ -1052,7 +1065,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .upgrade_vault(child_sc_address, new_code, opt_arg) .returns(ReturnsResultUnmanaged) @@ -1072,7 +1085,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .upgrade_vault_from_source(child_sc_address, source_address, opt_arg) .returns(ReturnsResultUnmanaged) @@ -1124,7 +1137,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .send_esdt(to, token_id, amount) .returns(ReturnsResultUnmanaged) @@ -1147,7 +1160,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .send_esdt_with_fees(to, percentage_fees) .payment(( @@ -1173,7 +1186,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .send_esdt_twice(to, token_id, amount_first_time, amount_second_time) .returns(ReturnsResultUnmanaged) @@ -1200,7 +1213,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .send_esdt_direct_multi_transfer(to, token_payments) .returns(ReturnsResultUnmanaged) @@ -1222,7 +1235,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .issue_fungible_token(token_display_name, token_ticker, initial_supply) .egld(egld_amount) @@ -1242,7 +1255,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .local_mint(token_identifier, amount) .returns(ReturnsResultUnmanaged) @@ -1261,7 +1274,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .local_burn(token_identifier, amount) .returns(ReturnsResultUnmanaged) @@ -1382,7 +1395,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .sft_issue(token_display_name, token_ticker) .egld(egld_amount) @@ -1424,7 +1437,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .buy_nft(nft_id, nft_nonce, nft_amount) .payment(( @@ -1450,7 +1463,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .nft_issue(token_display_name, token_ticker) .egld(egld_amount) @@ -1461,23 +1474,35 @@ impl ContractInteract { println!("Result: {response:?}"); } - pub async fn nft_create(&mut self) { - let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); - let amount = BigUint::::from(0u128); - let name = ManagedBuffer::new_from_bytes(&b""[..]); - let royalties = BigUint::::from(0u128); - let hash = ManagedBuffer::new_from_bytes(&b""[..]); - let color = Color::default(); - let uri = ManagedBuffer::new_from_bytes(&b""[..]); + #[allow(clippy::too_many_arguments)] + pub async fn nft_create( + &mut self, + token_id: &[u8], + amount: RustBigUint, + name: &[u8], + royalties: u64, + hash: &[u8], + attributes: &Color, + uri: &[u8], + ) { + println!("Minting NFT..."); let response = self .interactor .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) - .nft_create(token_identifier, amount, name, royalties, hash, color, uri) + .nft_create( + token_id, + amount, + name, + royalties, + hash, + attributes, + &ManagedBuffer::from(uri), + ) .returns(ReturnsResultUnmanaged) .run() .await; @@ -1495,7 +1520,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .nft_create_compact(token_identifier, amount, color) .returns(ReturnsResultUnmanaged) @@ -1515,7 +1540,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .nft_add_uris(token_identifier, nonce, uris) .returns(ReturnsResultUnmanaged) @@ -1535,7 +1560,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .nft_update_attributes(token_identifier, nonce, new_attributes) .returns(ReturnsResultUnmanaged) @@ -1571,7 +1596,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .nft_decode_complex_attributes( token_identifier, @@ -1599,7 +1624,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .nft_add_quantity(token_identifier, nonce, amount) .returns(ReturnsResultUnmanaged) @@ -1619,7 +1644,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .nft_burn(token_identifier, nonce, amount) .returns(ReturnsResultUnmanaged) @@ -1640,7 +1665,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .transfer_nft_via_async_call(to, token_identifier, nonce, amount) .returns(ReturnsResultUnmanaged) @@ -1663,7 +1688,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .transfer_nft_and_execute(to, token_identifier, nonce, amount, function, arguments) .returns(ReturnsResultUnmanaged) @@ -1688,7 +1713,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .create_and_send( to, @@ -1717,7 +1742,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .set_local_roles(address, token_identifier, roles) .returns(ReturnsResultUnmanaged) @@ -1737,7 +1762,7 @@ impl ContractInteract { .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .unset_local_roles(address, token_identifier, roles) .returns(ReturnsResultUnmanaged) @@ -1747,23 +1772,25 @@ impl ContractInteract { println!("Result: {response:?}"); } - pub async fn issue_dynamic_token(&mut self) { - let egld_amount = BigUint::::from(0u128); - - let token_display_name = ManagedBuffer::new_from_bytes(&b""[..]); - let token_ticker = ManagedBuffer::new_from_bytes(&b""[..]); - let token_type = EsdtTokenType::DynamicNFT; - let num_decimals = 0u32; + pub async fn issue_dynamic_token( + &mut self, + issue_cost: RustBigUint, + token_display_name: &[u8], + token_ticker: &[u8], + token_type: EsdtTokenType, + num_decimals: usize, + ) { + println!("Registering dynamic token {token_ticker:?} of type {token_type:?}..."); let response = self .interactor .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .issue_dynamic_token(token_display_name, token_ticker, token_type, num_decimals) - .egld(egld_amount) + .egld(BigUint::from(issue_cost)) .returns(ReturnsResultUnmanaged) .run() .await; @@ -1771,17 +1798,43 @@ impl ContractInteract { println!("Result: {response:?}"); } - pub async fn change_to_dynamic(&mut self) { - let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); + pub async fn issue_token_all_roles( + &mut self, + issue_cost: RustBigUint, + token_display_name: &[u8], + token_ticker: &[u8], + num_decimals: usize, + token_type: EsdtTokenType, + ) { + println!("Registering and setting all roles for token {token_ticker:?} of type {token_type:?}..."); + + let result = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(80_000_000u64) + .typed(proxy::ForwarderProxy) + .issue_token_all_roles(token_display_name, token_ticker, token_type, num_decimals) + .egld(BigUint::from(issue_cost)) + .returns(ReturnsResultUnmanaged) + .run() + .await; + + println!("Result: {result:?}"); + } + + pub async fn change_to_dynamic(&mut self, token_id: &[u8]) { + println!("Changing the following token {token_id:?} to dynamic..."); let response = self .interactor .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) - .change_to_dynamic(token_id) + .change_to_dynamic(TokenIdentifier::from(token_id)) .returns(ReturnsResultUnmanaged) .run() .await; @@ -1789,17 +1842,15 @@ impl ContractInteract { println!("Result: {response:?}"); } - pub async fn update_token(&mut self) { - let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); - + pub async fn update_token(&mut self, token_id: &[u8]) { let response = self .interactor .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) - .update_token(token_id) + .update_token(TokenIdentifier::from(token_id)) .returns(ReturnsResultUnmanaged) .run() .await; @@ -1807,19 +1858,17 @@ impl ContractInteract { println!("Result: {response:?}"); } - pub async fn modify_royalties(&mut self) { - let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); - let nonce = 0u64; - let new_royalty = 0u64; + pub async fn modify_royalties(&mut self, token_id: &[u8], nonce: u64, new_royalty: u64) { + println!("Modifying royalties for token {token_id:?} into {new_royalty:?}..."); let response = self .interactor .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) - .modify_royalties(token_id, nonce, new_royalty) + .modify_royalties(TokenIdentifier::from(token_id), nonce, new_royalty) .returns(ReturnsResultUnmanaged) .run() .await; @@ -1827,19 +1876,20 @@ impl ContractInteract { println!("Result: {response:?}"); } - pub async fn set_new_uris(&mut self) { - let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); - let nonce = 0u64; - let new_uris = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); + pub async fn set_new_uris(&mut self, token_id: &[u8], nonce: u64, new_uris: Vec) { + let uris = new_uris + .into_iter() + .map(ManagedBuffer::from) + .collect::>>(); let response = self .interactor .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) - .set_new_uris(token_id, nonce, new_uris) + .set_new_uris(token_id, nonce, uris) .returns(ReturnsResultUnmanaged) .run() .await; @@ -1847,18 +1897,15 @@ impl ContractInteract { println!("Result: {response:?}"); } - pub async fn modify_creator(&mut self) { - let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); - let nonce = 0u64; - + pub async fn modify_creator(&mut self, token_id: &[u8], nonce: u64) { let response = self .interactor .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) - .modify_creator(token_id, nonce) + .modify_creator(TokenIdentifier::from(token_id), nonce) .returns(ReturnsResultUnmanaged) .run() .await; @@ -1866,21 +1913,30 @@ impl ContractInteract { println!("Result: {response:?}"); } - pub async fn metadata_recreate(&mut self) { - let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); - let nonce = 0u64; - let name = ManagedBuffer::new_from_bytes(&b""[..]); - let royalties = 0u64; - let hash = ManagedBuffer::new_from_bytes(&b""[..]); - let new_attributes = Color::default(); - let uris = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); + #[allow(clippy::too_many_arguments)] + pub async fn metadata_recreate( + &mut self, + token_id: &[u8], + nonce: u64, + name: &[u8], + royalties: u64, + hash: &[u8], + new_attributes: &Color, + uris: Vec, + ) { + println!("Recreating the token {token_id:?} with nonce {nonce:?} with new attributes..."); + + let uris = uris + .into_iter() + .map(ManagedBuffer::from) + .collect::>>(); let response = self .interactor .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .metadata_recreate(token_id, nonce, name, royalties, hash, new_attributes, uris) .returns(ReturnsResultUnmanaged) @@ -1890,21 +1946,30 @@ impl ContractInteract { println!("Result: {response:?}"); } - pub async fn metadata_update(&mut self) { - let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); - let nonce = 0u64; - let name = ManagedBuffer::new_from_bytes(&b""[..]); - let royalties = 0u64; - let hash = ManagedBuffer::new_from_bytes(&b""[..]); - let new_attributes = Color::default(); - let uris = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); + #[allow(clippy::too_many_arguments)] + pub async fn metadata_update( + &mut self, + token_id: &[u8], + nonce: u64, + name: &[u8], + royalties: u64, + hash: &[u8], + new_attributes: &Color, + uris: Vec, + ) { + println!("Updating the token {token_id:?} with nonce {nonce:?} with new attributes..."); + + let uris = uris + .into_iter() + .map(ManagedBuffer::from) + .collect::>>(); let response = self .interactor .tx() .from(&self.wallet_address) .to(self.state.current_address()) - .gas(30_000_000u64) + .gas(80_000_000u64) .typed(proxy::ForwarderProxy) .metadata_update(token_id, nonce, name, royalties, hash, new_attributes, uris) .returns(ReturnsResultUnmanaged) @@ -1914,7 +1979,7 @@ impl ContractInteract { println!("Result: {response:?}"); } - pub async fn last_issued_token(&mut self) { + pub async fn last_issued_token(&mut self) -> String { let result_value = self .interactor .query() @@ -1926,6 +1991,8 @@ impl ContractInteract { .await; println!("Result: {result_value:?}"); + + result_value.as_managed_buffer().to_string() } pub async fn last_error_message(&mut self) { @@ -1941,4 +2008,108 @@ impl ContractInteract { println!("Result: {result_value:?}"); } + + pub async fn issue_dynamic_token_from_wallet( + &mut self, + issue_cost: RustBigUint, + token_display_name: &[u8], + token_ticker: &[u8], + token_type: EsdtTokenType, + num_decimals: usize, + ) -> String { + println!("Registering dynamic token {token_ticker:?} of type {token_type:?} from the test wallet..."); + + let token_id = self + .interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .issue_dynamic( + issue_cost.into(), + token_display_name, + token_ticker, + token_type, + num_decimals, + ) + .returns(ReturnsNewTokenIdentifier) + .run() + .await; + + println!("TOKEN ID: {:?}", token_id); + + token_id + } + + pub async fn set_roles_from_wallet( + &mut self, + for_address: &Address, + token_id: &[u8], + roles: Vec, + ) { + println!("Setting the following roles: {roles:?} for {token_id:?}"); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(80_000_000u64) + .typed(ESDTSystemSCProxy) + .set_special_roles( + ManagedAddress::from_address(for_address), + TokenIdentifier::from(token_id), + roles.into_iter(), + ) + .run() + .await; + } + + #[allow(clippy::too_many_arguments)] + pub async fn mint_nft_from_wallet( + &mut self, + token_id: &[u8], + amount: RustBigUint, + name: &[u8], + royalties: u64, + hash: &[u8], + attributes: &T, + uris: Vec, + ) -> u64 { + println!("Minting NFT..."); + + let uris = uris + .into_iter() + .map(ManagedBuffer::from) + .collect::>>(); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.wallet_address) + .gas(100_000_000u64) + .typed(UserBuiltinProxy) + .esdt_nft_create(token_id, amount, name, royalties, hash, attributes, &uris) + .returns(ReturnsResult) + .run() + .await + } + + pub async fn send_esdt_from_wallet( + &mut self, + to: &Address, + token_id: &[u8], + nonce: u64, + amount: RustBigUint, + ) { + println!("Sending token {token_id:?} with nonce {nonce:?} to other_wallet_address..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(to) + .single_esdt(&token_id.into(), nonce, &amount.into()) // .transfer() + .run() + .await; + } } diff --git a/contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs b/contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs index b27ce77f88..efa27be50f 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs +++ b/contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs @@ -1192,6 +1192,27 @@ where .original_result() } + pub fn issue_token_all_roles< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + token_type: Arg2, + num_decimals: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("issue_token_all_roles") + .argument(&token_display_name) + .argument(&token_ticker) + .argument(&token_type) + .argument(&num_decimals) + .original_result() + } + pub fn change_to_dynamic< Arg0: ProxyArg>, >( diff --git a/contracts/feature-tests/composability/forwarder-interactor/state.toml b/contracts/feature-tests/composability/forwarder-interactor/state.toml index 0bf61e6358..2db4efcb4e 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/state.toml +++ b/contracts/feature-tests/composability/forwarder-interactor/state.toml @@ -1 +1 @@ -contract_address = "erd1qqqqqqqqqqqqqpgqcr2nq237tg5vr3ezjvr750spkmtsjstjd8ssfp6eun" +contract_address = "erd1qqqqqqqqqqqqqpgqm6d7cp70y7ft6xe78f7np9agdm7vpce6d8sskuuxnu" diff --git a/contracts/feature-tests/composability/forwarder-interactor/tests/interact_cs_tests.rs b/contracts/feature-tests/composability/forwarder-interactor/tests/interact_cs_tests.rs index b85fc01bf3..62a9c9d1a0 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/tests/interact_cs_tests.rs +++ b/contracts/feature-tests/composability/forwarder-interactor/tests/interact_cs_tests.rs @@ -1,4 +1,4 @@ -use forwarder_interact::ContractInteract; +use forwarder_interact::{Config, ContractInteract}; use multiversx_sc_snippets::imports::*; // Simple deploy test that runs using the chain simulator configuration. @@ -9,7 +9,7 @@ use multiversx_sc_snippets::imports::*; #[tokio::test] #[cfg_attr(not(feature = "chain-simulator-tests"), ignore)] async fn deploy_test_forwarder_cs() { - let mut interactor = ContractInteract::new().await; + let mut interactor = ContractInteract::new(Config::chain_simulator_config(), None).await; interactor.deploy().await; } diff --git a/contracts/feature-tests/composability/forwarder-interactor/tests/interact_tests.rs b/contracts/feature-tests/composability/forwarder-interactor/tests/interact_tests.rs index 2005f0176f..59edcbbac0 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/tests/interact_tests.rs +++ b/contracts/feature-tests/composability/forwarder-interactor/tests/interact_tests.rs @@ -1,13 +1,341 @@ -use forwarder_interact::ContractInteract; +use forwarder_interact::{ + Color, Config, ContractInteract, FORWARDER_BUILTIN_INTERACTOR_TRACE_PATH, + FORWARDER_CHANGE_TO_DYNAMIC_INTERACTOR_TRACE_PATH, FORWARDER_DEPLOY_INTERACTOR_TRACE_PATH, + FORWARDER_MODIFY_CREATOR_INTERACTOR_TRACE_PATH, FORWARDER_UPDATE_TOKEN_INTERACTOR_TRACE_PATH, +}; use multiversx_sc_snippets::imports::*; +const ISSUE_COST: u64 = 50000000000000000u64; + // Simple deploy test that runs on the real blockchain configuration. // In order for this test to work, make sure that the `config.toml` file contains the real blockchain config (or choose it manually) // Can be run with `sc-meta test`. #[tokio::test] #[ignore = "run on demand, relies on real blockchain state"] async fn deploy_test_forwarder() { - let mut interactor = ContractInteract::new().await; + let mut interactor = + ContractInteract::new(Config::new(), Some(FORWARDER_DEPLOY_INTERACTOR_TRACE_PATH)).await; interactor.deploy().await; } + +#[tokio::test] +#[ignore = "run on demand"] +async fn builtin_func_tokens_test() { + let mut interact = + ContractInteract::new(Config::new(), Some(FORWARDER_BUILTIN_INTERACTOR_TRACE_PATH)).await; + + // deploy forwarder + interact.deploy().await; + + // issue dynamic NFT + interact + .issue_dynamic_token( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + EsdtTokenType::DynamicNFT, + 0usize, + ) + .await; + + // issue dynamic SFT + interact + .issue_dynamic_token( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + EsdtTokenType::DynamicSFT, + 0usize, + ) + .await; + + // issue dynamic META + interact + .issue_dynamic_token( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + EsdtTokenType::DynamicMeta, + 18usize, + ) + .await; + + // issue dynamic META with all roles + interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 0usize, + EsdtTokenType::DynamicMeta, + ) + .await; + + // issue dynamic SFT with all roles + interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 0usize, + EsdtTokenType::DynamicSFT, + ) + .await; + + // issue dynamic NFT with all roles + interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 0usize, + EsdtTokenType::DynamicNFT, + ) + .await; + + let dynamic_nft_token_id = interact.last_issued_token().await; + + println!("Dynamic NFT token id issued: {dynamic_nft_token_id:?}"); + + // mint NFT + interact + .nft_create( + dynamic_nft_token_id.as_bytes(), + RustBigUint::from(1u64), + b"myNFT", + 30u64, + b"", + &Color { + r: 1u8, + g: 2u8, + b: 5u8, + }, + b"sample_uri", + ) + .await; + + let nonce = 1u64; + + println!("Dynamic NFT minted at nonce {nonce:?}"); + + // modify royalties + interact + .modify_royalties(dynamic_nft_token_id.as_bytes(), nonce, 20u64) + .await; + + println!("Royalties changed for {dynamic_nft_token_id:?} with nonce {nonce:?}"); + + // set new uris + let uris = vec!["thisianuri.com".to_string()]; + interact + .set_new_uris(dynamic_nft_token_id.as_bytes(), nonce, uris) + .await; + + println!("New uris set for {dynamic_nft_token_id:?} with nonce {nonce:?}"); + + // metadata update + interact + .metadata_update( + dynamic_nft_token_id.as_bytes(), + nonce, + b"TESTNFT", + 30u64, + b"new_hash", + &Color { + r: 6u8, + g: 7u8, + b: 8u8, + }, + Vec::new(), + ) + .await; + + println!("Metadata updated for {dynamic_nft_token_id:?} with nonce {nonce:?}"); + + // metadata recreate + interact + .metadata_recreate( + dynamic_nft_token_id.as_bytes(), + nonce, + b"TESTNFT", + 30u64, + b"new_hash_recreated", + &Color { + r: 8u8, + g: 8u8, + b: 8u8, + }, + Vec::new(), + ) + .await; + + println!("Metadata recreated for {dynamic_nft_token_id:?} with nonce {nonce:?}. A new token has been created."); +} + +#[tokio::test] +#[ignore = "run on demand"] +async fn change_to_dynamic_test() { + let mut interact = ContractInteract::new( + Config::new(), + Some(FORWARDER_CHANGE_TO_DYNAMIC_INTERACTOR_TRACE_PATH), + ) + .await; + + // deploy forwarder + interact.deploy().await; + + // issue NFT with all roles + interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 0usize, + EsdtTokenType::NonFungible, + ) + .await; + + // issue META token with all roles + interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 18usize, + EsdtTokenType::Meta, + ) + .await; + + // get token id from the contract + let meta_token_id = interact.last_issued_token().await; + + // change META to dynamic + interact.change_to_dynamic(meta_token_id.as_bytes()).await; + + // issue SFT token with all roles + interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 18usize, + EsdtTokenType::SemiFungible, + ) + .await; + + // get token id from the contract + let sft_token_id = interact.last_issued_token().await; + + // change SFT to dynamic + interact.change_to_dynamic(sft_token_id.as_bytes()).await; +} + +#[tokio::test] +#[ignore = "run on demand"] +async fn update_token_test() { + let mut interact = ContractInteract::new( + Config::new(), + Some(FORWARDER_UPDATE_TOKEN_INTERACTOR_TRACE_PATH), + ) + .await; + + // deploy forwarder + interact.deploy().await; + + // issue NFT with all roles + interact + .issue_token_all_roles( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + 0usize, + EsdtTokenType::NonFungible, + ) + .await; + + // get token id from the contract + let nft_token_id = interact.last_issued_token().await; + + // update NFT + interact.update_token(nft_token_id.as_bytes()).await; +} + +#[tokio::test] +#[ignore = "run on demand"] +async fn modify_creator() { + let mut interact = ContractInteract::new( + Config::new(), + Some(FORWARDER_MODIFY_CREATOR_INTERACTOR_TRACE_PATH), + ) + .await; + + // deploy forwarder + interact.deploy().await; + + let wallet_address = interact.wallet_address.clone(); + let sc_address = interact.state.current_address().clone(); + + // issue dynamic NFT + let dynamic_nft_token_id = interact + .issue_dynamic_token_from_wallet( + RustBigUint::from(ISSUE_COST), + b"TESTNFT", + b"TEST", + EsdtTokenType::DynamicNFT, + 0usize, + ) + .await; + + // set roles for self to mint + interact + .set_roles_from_wallet( + &wallet_address, + dynamic_nft_token_id.as_bytes(), + vec![EsdtLocalRole::NftCreate], + ) + .await; + + // mint NFT + let nonce = interact + .mint_nft_from_wallet( + dynamic_nft_token_id.as_bytes(), + RustBigUint::from(1u64), + b"myNFT", + 30u64, + b"", + &Color { + r: 1u8, + g: 2u8, + b: 3u8, + }, + Vec::new(), + ) + .await; + + println!("Dynamic NFT minted at nonce {nonce:?}"); + + // set modify creator role for the contract + interact + .set_roles_from_wallet( + &sc_address.to_address(), + dynamic_nft_token_id.as_bytes(), + vec![EsdtLocalRole::ModifyCreator], + ) + .await; + + // send nft to the contract + interact + .send_esdt_from_wallet( + &sc_address.to_address(), + dynamic_nft_token_id.as_bytes(), + 1u64, + 1u64.into(), + ) + .await; + + // modify creator into the contract (from wallet to SC through a SC call) + interact + .modify_creator(dynamic_nft_token_id.as_bytes(), nonce) + .await; +} diff --git a/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs b/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs index b27ce77f88..efa27be50f 100644 --- a/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs +++ b/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs @@ -1192,6 +1192,27 @@ where .original_result() } + pub fn issue_token_all_roles< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + token_type: Arg2, + num_decimals: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("issue_token_all_roles") + .argument(&token_display_name) + .argument(&token_ticker) + .argument(&token_type) + .argument(&num_decimals) + .original_result() + } + pub fn change_to_dynamic< Arg0: ProxyArg>, >( diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs b/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs index f7a53c8f84..14549d99ad 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs @@ -31,12 +31,37 @@ pub trait ForwarderDynamicModule: .async_call_and_exit(); } + #[payable["EGLD"]] + #[endpoint] + fn issue_token_all_roles( + &self, + token_display_name: ManagedBuffer, + token_ticker: ManagedBuffer, + token_type: EsdtTokenType, + num_decimals: usize, + ) { + let issue_cost = self.call_value().egld_value().clone_value(); + let caller = self.blockchain().get_caller(); + + self.send() + .esdt_system_sc_proxy() + .issue_and_set_all_roles( + issue_cost, + token_display_name, + token_ticker, + token_type, + num_decimals, + ) + .callback(self.callbacks().nft_issue_callback(&caller)) + .async_call_and_exit(); + } + #[endpoint] fn change_to_dynamic(&self, token_id: TokenIdentifier) { self.send() .esdt_system_sc_proxy() .change_to_dynamic(token_id) - .sync_call(); + .async_call_and_exit(); } #[endpoint] @@ -44,7 +69,7 @@ pub trait ForwarderDynamicModule: self.send() .esdt_system_sc_proxy() .update_token(token_id) - .sync_call(); + .async_call_and_exit(); } #[endpoint] diff --git a/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs b/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs index 7b6e32ddea..b9be382059 100644 --- a/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs @@ -5,9 +5,9 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 77 +// Endpoints: 78 // Async Callback: 1 -// Total number of exported functions: 79 +// Total number of exported functions: 80 #![no_std] @@ -86,6 +86,7 @@ multiversx_sc_wasm_adapter::endpoints! { setLocalRoles => set_local_roles unsetLocalRoles => unset_local_roles issue_dynamic_token => issue_dynamic_token + issue_token_all_roles => issue_token_all_roles change_to_dynamic => change_to_dynamic update_token => update_token modify_royalties => modify_royalties From 9182948db6040e49383ce796499b70326b52f76d Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Mon, 9 Dec 2024 17:34:16 +0100 Subject: [PATCH 079/133] scenarios go tests --- .../tests/scenarios_go_tests.rs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 contracts/feature-tests/composability/forwarder-interactor/tests/scenarios_go_tests.rs diff --git a/contracts/feature-tests/composability/forwarder-interactor/tests/scenarios_go_tests.rs b/contracts/feature-tests/composability/forwarder-interactor/tests/scenarios_go_tests.rs new file mode 100644 index 0000000000..5af1edc7d5 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-interactor/tests/scenarios_go_tests.rs @@ -0,0 +1,30 @@ +use multiversx_sc_snippets::multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + ScenarioWorld::vm_go() +} + +#[test] +fn deploy_go() { + world().run("scenarios/forwarder_deploy_scenario.scen.json"); +} + +#[test] +fn builtin_func_go() { + world().run("scenarios/forwarder_builtin_scenario.scen.json"); +} + +#[test] +fn change_to_dynamic_go() { + world().run("scenarios/forwarder_change_to_dynamic_scenario.scen.json"); +} + +#[test] +fn update_token_go() { + world().run("scenarios/forwarder_update_token_scenario.scen.json"); +} + +#[test] +fn modify_creator_go() { + world().run("scenarios/forwarder_modify_creator_scenario.scen.json"); +} From bc71228b7946df0b4c7a4aca80230aecd8cdf491 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Mon, 9 Dec 2024 18:04:23 +0100 Subject: [PATCH 080/133] ignore tests (missing syntax), accounts fix --- .../scenarios/forwarder_builtin_scenario.scen.json | 8 +++++++- .../forwarder_change_to_dynamic_scenario.scen.json | 8 +++++++- .../scenarios/forwarder_deploy_scenario.scen.json | 8 +++++++- .../scenarios/forwarder_modify_creator_scenario.scen.json | 6 ++++++ .../scenarios/forwarder_update_token_scenario.scen.json | 6 ++++++ .../forwarder-interactor/tests/scenarios_go_tests.rs | 4 ++++ 6 files changed, 37 insertions(+), 3 deletions(-) diff --git a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_builtin_scenario.scen.json b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_builtin_scenario.scen.json index 7bdf624811..29820bc45e 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_builtin_scenario.scen.json +++ b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_builtin_scenario.scen.json @@ -2,6 +2,12 @@ "steps": [ { "step": "setState", + "accounts": { + "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1": { + "nonce": "11899", + "balance": "100" + } + }, "newAddresses": [ { "creatorAddress": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", @@ -309,4 +315,4 @@ } } ] -} +} \ No newline at end of file diff --git a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_change_to_dynamic_scenario.scen.json b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_change_to_dynamic_scenario.scen.json index ba64c01c26..5833c698a2 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_change_to_dynamic_scenario.scen.json +++ b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_change_to_dynamic_scenario.scen.json @@ -2,6 +2,12 @@ "steps": [ { "step": "setState", + "accounts": { + "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1": { + "nonce": "11911", + "balance": "100" + } + }, "newAddresses": [ { "creatorAddress": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", @@ -170,4 +176,4 @@ } } ] -} +} \ No newline at end of file diff --git a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_deploy_scenario.scen.json b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_deploy_scenario.scen.json index 09281ed0f3..d105846d4f 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_deploy_scenario.scen.json +++ b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_deploy_scenario.scen.json @@ -2,6 +2,12 @@ "steps": [ { "step": "setState", + "accounts": { + "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1": { + "nonce": "11920", + "balance": "100" + } + }, "newAddresses": [ { "creatorAddress": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", @@ -25,4 +31,4 @@ } } ] -} +} \ No newline at end of file diff --git a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_modify_creator_scenario.scen.json b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_modify_creator_scenario.scen.json index fe3e78431e..2319138ca6 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_modify_creator_scenario.scen.json +++ b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_modify_creator_scenario.scen.json @@ -2,6 +2,12 @@ "steps": [ { "step": "setState", + "accounts": { + "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1": { + "nonce": "11928", + "balance": "100" + } + }, "newAddresses": [ { "creatorAddress": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", diff --git a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_update_token_scenario.scen.json b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_update_token_scenario.scen.json index 4ddfaab647..9724dab7d0 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_update_token_scenario.scen.json +++ b/contracts/feature-tests/composability/forwarder-interactor/scenarios/forwarder_update_token_scenario.scen.json @@ -2,6 +2,12 @@ "steps": [ { "step": "setState", + "accounts": { + "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1": { + "nonce": "11917", + "balance": "100" + } + }, "newAddresses": [ { "creatorAddress": "0x0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", diff --git a/contracts/feature-tests/composability/forwarder-interactor/tests/scenarios_go_tests.rs b/contracts/feature-tests/composability/forwarder-interactor/tests/scenarios_go_tests.rs index 5af1edc7d5..6950bf2f5c 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/tests/scenarios_go_tests.rs +++ b/contracts/feature-tests/composability/forwarder-interactor/tests/scenarios_go_tests.rs @@ -10,21 +10,25 @@ fn deploy_go() { } #[test] +#[ignore = "missing 'newTokenIdentifiers' syntax"] fn builtin_func_go() { world().run("scenarios/forwarder_builtin_scenario.scen.json"); } #[test] +#[ignore = "missing 'newTokenIdentifiers' syntax"] fn change_to_dynamic_go() { world().run("scenarios/forwarder_change_to_dynamic_scenario.scen.json"); } #[test] +#[ignore = "missing 'newTokenIdentifiers' syntax"] fn update_token_go() { world().run("scenarios/forwarder_update_token_scenario.scen.json"); } #[test] +#[ignore = "missing 'newTokenIdentifiers' syntax"] fn modify_creator_go() { world().run("scenarios/forwarder_modify_creator_scenario.scen.json"); } From 65f9681f6773af6dc2c35df3b50abdb687bd70cc Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 11 Dec 2024 17:35:25 +0200 Subject: [PATCH 081/133] EndpointWrappers call_* method refactor --- .../tests/price_aggregator_whitebox_test.rs | 15 ++- framework/derive/src/contract_impl.rs | 8 +- .../derive/src/generate/endpoints_mod_gen.rs | 4 +- .../derive/src/generate/function_selector.rs | 15 ++- .../derive/src/generate/method_call_gen.rs | 2 +- framework/derive/src/generate/snippets.rs | 3 +- .../scenario/tests/contract_without_macros.rs | 97 ++++++++++++++----- 7 files changed, 93 insertions(+), 51 deletions(-) diff --git a/contracts/core/price-aggregator/tests/price_aggregator_whitebox_test.rs b/contracts/core/price-aggregator/tests/price_aggregator_whitebox_test.rs index f44d9f76fc..a23edf113a 100644 --- a/contracts/core/price-aggregator/tests/price_aggregator_whitebox_test.rs +++ b/contracts/core/price-aggregator/tests/price_aggregator_whitebox_test.rs @@ -2,10 +2,7 @@ use multiversx_price_aggregator_sc::{ price_aggregator_data::{OracleStatus, TimestampedPrice, TokenPair}, PriceAggregator, MAX_ROUND_DURATION_SECONDS, }; -use multiversx_sc_modules::{ - pause::EndpointWrappers as PauseEndpointWrappers, - staking::{EndpointWrappers as StakingEndpointWrappers, StakingModule}, -}; +use multiversx_sc_modules::{pause::PauseModule, staking::StakingModule}; use multiversx_sc_scenario::imports::*; pub const DECIMALS: u8 = 0; @@ -73,7 +70,7 @@ fn test_price_aggregator_submit() { .from(OWNER_ADDRESS) .to(PRICE_AGGREGATOR_ADDRESS) .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { - sc.call_unpause_endpoint(); + sc.unpause_endpoint(); }); // submit first timestamp too old @@ -197,7 +194,7 @@ fn test_price_aggregator_submit_round_ok() { .from(OWNER_ADDRESS) .to(PRICE_AGGREGATOR_ADDRESS) .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { - sc.call_unpause_endpoint(); + sc.unpause_endpoint(); }); // submit first @@ -304,7 +301,7 @@ fn test_price_aggregator_discarded_round() { .from(OWNER_ADDRESS) .to(PRICE_AGGREGATOR_ADDRESS) .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { - sc.call_unpause_endpoint(); + sc.unpause_endpoint(); }); // submit first @@ -380,7 +377,7 @@ fn test_price_aggregator_slashing() { .from(OWNER_ADDRESS) .to(PRICE_AGGREGATOR_ADDRESS) .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { - sc.call_unpause_endpoint(); + sc.unpause_endpoint(); }); world @@ -489,7 +486,7 @@ fn setup() -> (ScenarioWorld, Vec

) { .to(PRICE_AGGREGATOR_ADDRESS) .egld(STAKE_AMOUNT) .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { - sc.call_stake(); + sc.stake(); }); } diff --git a/framework/derive/src/contract_impl.rs b/framework/derive/src/contract_impl.rs index 1f6b3c9383..b10d66d3ad 100644 --- a/framework/derive/src/contract_impl.rs +++ b/framework/derive/src/contract_impl.rs @@ -52,7 +52,7 @@ pub fn contract_implementation( impl #trait_name_ident for C where - C: AutoImpl #(#supertraits_main)* + C: AutoImpl #(#supertraits_main)* { #(#auto_impls)* @@ -75,15 +75,15 @@ pub fn contract_implementation( { #(#call_methods)* - fn call(&self, fn_name: &str) -> bool { + fn call(&mut self, fn_name: &str) -> bool { #function_selector_body } - fn callback_selector(&self, mut ___cb_closure___: multiversx_sc::types::CallbackClosureForDeser) -> multiversx_sc::types::CallbackSelectorResult { + fn callback_selector(&mut self, mut ___cb_closure___: multiversx_sc::types::CallbackClosureForDeser) -> multiversx_sc::types::CallbackSelectorResult { #callback_selector_body } - fn callback(&self) { + fn callback(&mut self) { #callback_body } } diff --git a/framework/derive/src/generate/endpoints_mod_gen.rs b/framework/derive/src/generate/endpoints_mod_gen.rs index 4bba840a90..e30ac37604 100644 --- a/framework/derive/src/generate/endpoints_mod_gen.rs +++ b/framework/derive/src/generate/endpoints_mod_gen.rs @@ -37,7 +37,7 @@ pub fn generate_endpoints_mod( A: multiversx_sc::api::VMApi , { super::EndpointWrappers::callback( - &multiversx_sc::contract_base::UniversalContractObj::::new(), + &mut multiversx_sc::contract_base::UniversalContractObj::::new(), ); } } @@ -93,7 +93,7 @@ fn generate_wasm_endpoint( A: multiversx_sc::api::VMApi, { super::EndpointWrappers::#call_method_ident( - &multiversx_sc::contract_base::UniversalContractObj::::new(), + &mut multiversx_sc::contract_base::UniversalContractObj::::new(), ); } } diff --git a/framework/derive/src/generate/function_selector.rs b/framework/derive/src/generate/function_selector.rs index 6f157724f8..3aed56f622 100644 --- a/framework/derive/src/generate/function_selector.rs +++ b/framework/derive/src/generate/function_selector.rs @@ -48,21 +48,20 @@ pub fn generate_function_selector_body(contract: &ContractTrait) -> proc_macro2: let module_calls = supertrait_gen::function_selector_module_calls(contract.supertraits.as_slice()); quote! { - if match fn_name { + match fn_name { "callBack" => { self::EndpointWrappers::callback(self); - return true; + true }, "init" if ::external_view_init_override() => { multiversx_sc::external_view_contract::external_view_contract_constructor::(); - return true; + true }, #(#match_arms)* - other => false - } { - return true; + other => { + #(#module_calls)* + false + } } - #(#module_calls)* - false } } diff --git a/framework/derive/src/generate/method_call_gen.rs b/framework/derive/src/generate/method_call_gen.rs index a34db90f06..74d3f3ce4f 100644 --- a/framework/derive/src/generate/method_call_gen.rs +++ b/framework/derive/src/generate/method_call_gen.rs @@ -27,7 +27,7 @@ pub fn generate_call_method(m: &Method) -> proc_macro2::TokenStream { let call_method_body = generate_endpoint_call_method_body(m); quote! { #[inline] - fn #call_method_ident (&self) { + fn #call_method_ident (&mut self) { #call_method_body } } diff --git a/framework/derive/src/generate/snippets.rs b/framework/derive/src/generate/snippets.rs index 6e66eb9ae4..91fc8a863f 100644 --- a/framework/derive/src/generate/snippets.rs +++ b/framework/derive/src/generate/snippets.rs @@ -67,7 +67,8 @@ pub fn impl_callable_contract() -> proc_macro2::TokenStream { A: multiversx_sc::api::VMApi + Send + Sync, { fn call(&self, fn_name: &str) -> bool { - EndpointWrappers::call(self, fn_name) + let mut obj = multiversx_sc::contract_base::UniversalContractObj::::new(); + EndpointWrappers::call(&mut obj, fn_name) } } } diff --git a/framework/scenario/tests/contract_without_macros.rs b/framework/scenario/tests/contract_without_macros.rs index c597bb9e81..ccdcc493fd 100644 --- a/framework/scenario/tests/contract_without_macros.rs +++ b/framework/scenario/tests/contract_without_macros.rs @@ -9,7 +9,7 @@ #![allow(unused)] use multiversx_sc::{ - contract_base::ProxyObjNew, + contract_base::{CallableContractBuilder, ProxyObjNew}, types::{BigInt, ManagedAddress}, }; use multiversx_sc_scenario::api::{SingleTxApi, StaticApi}; @@ -57,19 +57,19 @@ mod module_1 { pub trait EndpointWrappers: VersionModule + multiversx_sc::contract_base::ContractBase { #[inline] - fn call_version(&self) { + fn call_version(&mut self) { multiversx_sc::io::call_value_init::not_payable::(); let result = self.version(); multiversx_sc::io::finish_multi::(&result) } - fn call_some_async(&self) { + fn call_some_async(&mut self) { self.some_async(); multiversx_sc::io::finish_multi::(&()) } - fn call(&self, fn_name: &str) -> bool { - if match fn_name { + fn call(&mut self, fn_name: &str) -> bool { + match fn_name { "callBack" => { self.callback(); return true; @@ -79,10 +79,13 @@ mod module_1 { true }, _other => false, - } { - return true; } - false + } + fn callback_selector( + &mut self, + mut ___cb_closure___: multiversx_sc::types::CallbackClosureForDeser, + ) -> multiversx_sc::types::CallbackSelectorResult { + multiversx_sc::types::CallbackSelectorResult::NotProcessed(___cb_closure___) } } @@ -277,7 +280,7 @@ mod sample_adder { Adder + multiversx_sc::contract_base::ContractBase + super::module_1::EndpointWrappers { #[inline] - fn call_sum(&self) { + fn call_sum(&mut self) { ::init_static(); multiversx_sc::io::call_value_init::not_payable::(); let () = multiversx_sc::io::load_endpoint_args::(()); @@ -285,7 +288,7 @@ mod sample_adder { multiversx_sc::io::finish_multi::(&result); } #[inline] - fn call_init(&self) { + fn call_init(&mut self) { ::init_static(); multiversx_sc::io::call_value_init::not_payable::(); let (initial_value, ()) = multiversx_sc::io::load_endpoint_args::< @@ -295,7 +298,7 @@ mod sample_adder { self.init(initial_value); } #[inline] - fn call_upgrade(&self) { + fn call_upgrade(&mut self) { ::init_static(); multiversx_sc::io::call_value_init::not_payable::(); let (initial_value, ()) = multiversx_sc::io::load_endpoint_args::< @@ -305,7 +308,7 @@ mod sample_adder { self.upgrade(initial_value); } #[inline] - fn call_add(&self) { + fn call_add(&mut self) { ::init_static(); multiversx_sc::io::call_value_init::not_payable::(); let (value, ()) = multiversx_sc::io::load_endpoint_args::< @@ -314,8 +317,8 @@ mod sample_adder { >(("value", ())); self.add(value); } - fn call(&self, fn_name: &str) -> bool { - if match fn_name { + fn call(&mut self, fn_name: &str) -> bool { + match fn_name { "callBack" => { self::EndpointWrappers::callback(self); return true; @@ -346,19 +349,58 @@ mod sample_adder { self.call_add(); true }, - other => false, - } { - return true; + other => { + if super::module_1::EndpointWrappers::call(self, fn_name) { + return true; + } + false + }, } - false } fn callback_selector( - &self, + &mut self, mut ___cb_closure___: multiversx_sc::types::CallbackClosureForDeser, ) -> multiversx_sc::types::CallbackSelectorResult { + let ___cb_closure_matcher___ = ___cb_closure___.matcher::<32usize>(); + if ___cb_closure_matcher___.matches_empty() { + return multiversx_sc::types::CallbackSelectorResult::Processed; + } + match super::module_1::EndpointWrappers::callback_selector(self, ___cb_closure___) { + multiversx_sc::types::CallbackSelectorResult::Processed => { + return multiversx_sc::types::CallbackSelectorResult::Processed; + }, + multiversx_sc::types::CallbackSelectorResult::NotProcessed( + recovered_cb_closure, + ) => { + ___cb_closure___ = recovered_cb_closure; + }, + } + match super::module_1::EndpointWrappers::callback_selector(self, ___cb_closure___) { + multiversx_sc::types::CallbackSelectorResult::Processed => { + return multiversx_sc::types::CallbackSelectorResult::Processed; + }, + multiversx_sc::types::CallbackSelectorResult::NotProcessed( + recovered_cb_closure, + ) => { + ___cb_closure___ = recovered_cb_closure; + }, + } multiversx_sc::types::CallbackSelectorResult::NotProcessed(___cb_closure___) } - fn callback(&self) {} + fn callback(&mut self) { + if let Some(___cb_closure___) = + multiversx_sc::types::CallbackClosureForDeser::storage_load_and_clear::() + { + if let multiversx_sc::types::CallbackSelectorResult::NotProcessed(_) = + self::EndpointWrappers::callback_selector(self, ___cb_closure___) + { + multiversx_sc::api::ErrorApiImpl::signal_error( + &::error_api_impl(), + err_msg::CALLBACK_BAD_FUNC.as_bytes(), + ); + } + } + } } impl EndpointWrappers for multiversx_sc::contract_base::UniversalContractObj where @@ -441,7 +483,7 @@ mod sample_adder { A: multiversx_sc::api::VMApi, { super::EndpointWrappers::call_sum( - &multiversx_sc::contract_base::UniversalContractObj::::new(), + &mut multiversx_sc::contract_base::UniversalContractObj::::new(), ); } pub fn init() @@ -449,7 +491,7 @@ mod sample_adder { A: multiversx_sc::api::VMApi, { super::EndpointWrappers::call_init( - &multiversx_sc::contract_base::UniversalContractObj::::new(), + &mut multiversx_sc::contract_base::UniversalContractObj::::new(), ); } pub fn upgrade() @@ -457,7 +499,7 @@ mod sample_adder { A: multiversx_sc::api::VMApi, { super::EndpointWrappers::call_upgrade( - &multiversx_sc::contract_base::UniversalContractObj::::new(), + &mut multiversx_sc::contract_base::UniversalContractObj::::new(), ); } pub fn add() @@ -465,7 +507,7 @@ mod sample_adder { A: multiversx_sc::api::VMApi, { super::EndpointWrappers::call_add( - &multiversx_sc::contract_base::UniversalContractObj::::new(), + &mut multiversx_sc::contract_base::UniversalContractObj::::new(), ); } pub fn callBack() @@ -473,7 +515,7 @@ mod sample_adder { A: multiversx_sc::api::VMApi, { super::EndpointWrappers::callback( - &multiversx_sc::contract_base::UniversalContractObj::::new(), + &mut multiversx_sc::contract_base::UniversalContractObj::::new(), ); } } @@ -597,7 +639,8 @@ mod sample_adder { A: multiversx_sc::api::VMApi, { fn call(&self, fn_name: &str) -> bool { - EndpointWrappers::call(self, fn_name) + let mut obj = multiversx_sc::contract_base::UniversalContractObj::::new(); + EndpointWrappers::call(&mut obj, fn_name) } } @@ -770,8 +813,10 @@ fn contract_without_macros_basic() { assert_eq!(BigInt::from(100), adder.version()); + let adder = sample_adder::ContractBuilder.new_contract_obj::(); assert!(!adder.call("invalid_endpoint")); + let adder = sample_adder::ContractBuilder.new_contract_obj::(); assert!(adder.call("getSum")); let mut own_proxy = From de3b6df1fa6ebabc69c8eefb34a38c390f738941 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 11 Dec 2024 18:25:56 +0200 Subject: [PATCH 082/133] cleanup, comments --- framework/scenario/tests/contract_without_macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/scenario/tests/contract_without_macros.rs b/framework/scenario/tests/contract_without_macros.rs index ccdcc493fd..d461adea6d 100644 --- a/framework/scenario/tests/contract_without_macros.rs +++ b/framework/scenario/tests/contract_without_macros.rs @@ -254,8 +254,6 @@ mod sample_adder { ///////////////////////////////////////////////////////////////////////////////////////////////// pub trait AutoImpl: multiversx_sc::contract_base::ContractBase {} - // impl super::module_1::AutoImpl for C where C: AutoImpl {} - impl Adder for C where C: AutoImpl + super::module_1::AutoImpl, @@ -639,6 +637,8 @@ mod sample_adder { A: multiversx_sc::api::VMApi, { fn call(&self, fn_name: &str) -> bool { + // creating a new object, which we can mutate + // because of dynamic traits, we cannot move `self` let mut obj = multiversx_sc::contract_base::UniversalContractObj::::new(); EndpointWrappers::call(&mut obj, fn_name) } From 81f28d55bc1d465e0abafa33e2181fa4368543ea Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 11 Dec 2024 20:34:09 +0200 Subject: [PATCH 083/133] refactor: ManagedResultArgLoader replaced with ManagedVec iterators --- .../contract_call_legacy/contract_deploy.rs | 4 +-- .../base/src/types/interaction/tx_exec.rs | 4 +-- .../multi_value/multi_value_encoded_iter.rs | 23 +++++++------ .../managed/wrapped/managed_vec_iter_owned.rs | 33 ++++++++++++++++++- .../wrapped/managed_vec_iter_payload.rs | 21 +++++++++--- .../managed/wrapped/managed_vec_iter_ref.rs | 33 ++++++++++++++++++- 6 files changed, 95 insertions(+), 23 deletions(-) diff --git a/framework/base/src/types/interaction/contract_call_legacy/contract_deploy.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_deploy.rs index 6b19010e3d..8b12548b30 100644 --- a/framework/base/src/types/interaction/contract_call_legacy/contract_deploy.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_deploy.rs @@ -9,7 +9,7 @@ use crate::{ api::{BlockchainApiImpl, CallTypeApi}, contract_base::{ExitCodecErrorHandler, SendRawWrapper}, err_msg, - io::{ArgErrorHandler, ArgId, ManagedResultArgLoader}, + io::{ArgErrorHandler, ArgId}, types::{ BigUint, CodeMetadata, ManagedAddress, ManagedArgBuffer, ManagedBuffer, ManagedOption, ManagedVec, @@ -112,7 +112,7 @@ where where RequestedResult: TopDecodeMulti + TypeAbiFrom, { - let mut loader = ManagedResultArgLoader::new(raw_result); + let mut loader = raw_result.into_iter(); let arg_id = ArgId::from(&b"init result"[..]); let h = ArgErrorHandler::::from(arg_id); RequestedResult::multi_decode_or_handle_err(&mut loader, h).unwrap_infallible() diff --git a/framework/base/src/types/interaction/tx_exec.rs b/framework/base/src/types/interaction/tx_exec.rs index 0c200df330..6f4ffc40d3 100644 --- a/framework/base/src/types/interaction/tx_exec.rs +++ b/framework/base/src/types/interaction/tx_exec.rs @@ -15,7 +15,7 @@ use unwrap_infallible::UnwrapInfallible; use crate::{ api::CallTypeApi, - io::{ArgErrorHandler, ArgId, ManagedResultArgLoader}, + io::{ArgErrorHandler, ArgId}, types::{ManagedBuffer, ManagedVec}, }; use multiversx_sc_codec::TopDecodeMulti; @@ -30,7 +30,7 @@ where SA: CallTypeApi + 'static, RequestedResult: TopDecodeMulti, { - let mut loader = ManagedResultArgLoader::new(raw_result); + let mut loader = raw_result.into_iter(); let arg_id = ArgId::from(&b"sync result"[..]); let h: ArgErrorHandler = ArgErrorHandler::::from(arg_id); RequestedResult::multi_decode_or_handle_err(&mut loader, h).unwrap_infallible() diff --git a/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs b/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs index 4b8db58ffb..670586fbf6 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs @@ -4,10 +4,10 @@ use unwrap_infallible::UnwrapInfallible; use crate::codec::{TopDecodeMulti, TopDecodeMultiInput}; -use crate::types::{ManagedBuffer, ManagedVec}; +use crate::types::{ManagedBuffer, ManagedVec, ManagedVecOwnedIterator}; use crate::{ api::{ErrorApi, ManagedTypeApi}, - io::{ArgErrorHandler, ArgId, ManagedResultArgLoader}, + io::{ArgErrorHandler, ArgId}, }; /// Iterator for `MultiValueEncoded` and `MultiValueEncodedCounted`. @@ -18,7 +18,7 @@ where M: ManagedTypeApi + ErrorApi, T: TopDecodeMulti, { - data_loader: ManagedResultArgLoader, + data_loader: ManagedVecOwnedIterator>, _phantom: PhantomData, } @@ -29,7 +29,7 @@ where { pub(crate) fn new(raw_buffers: ManagedVec>) -> Self { MultiValueEncodedIterator { - data_loader: ManagedResultArgLoader::new(raw_buffers), + data_loader: raw_buffers.into_iter(), _phantom: PhantomData, } } @@ -43,14 +43,13 @@ where type Item = T; fn next(&mut self) -> Option { - if self.data_loader.has_next() { - let arg_id = ArgId::from(&b"var args"[..]); - let h = ArgErrorHandler::::from(arg_id); - let result = - T::multi_decode_or_handle_err(&mut self.data_loader, h).unwrap_infallible(); - Some(result) - } else { - None + if !self.data_loader.has_next() { + return None; } + + let arg_id = ArgId::from(&b"var args"[..]); + let h = ArgErrorHandler::::from(arg_id); + let result = T::multi_decode_or_handle_err(&mut self.data_loader, h).unwrap_infallible(); + Some(result) } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs index 055b4b4a11..f4712e7464 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_owned.rs @@ -1,4 +1,9 @@ -use crate::{api::ManagedTypeApi, types::ManagedType}; +use multiversx_sc_codec::{DecodeError, DecodeErrorHandler, TopDecodeMultiInput}; + +use crate::{ + api::{ErrorApi, ManagedTypeApi}, + types::{ManagedBuffer, ManagedType}, +}; use super::{ManagedVec, ManagedVecItem, ManagedVecPayloadIterator}; @@ -34,6 +39,10 @@ where } } } + + pub(crate) fn iter_is_empty(&self) -> bool { + self.payload_iter.iter_is_empty() + } } impl Iterator for ManagedVecOwnedIterator @@ -70,3 +79,25 @@ where Some(T::read_from_payload(&payload)) } } + +impl TopDecodeMultiInput for ManagedVecOwnedIterator> +where + A: ManagedTypeApi + ErrorApi, +{ + type ValueInput = ManagedBuffer; + + fn has_next(&self) -> bool { + !self.iter_is_empty() + } + + fn next_value_input(&mut self, h: H) -> Result + where + H: DecodeErrorHandler, + { + if let Some(buffer) = self.next() { + Ok(buffer) + } else { + Err(h.handle_error(DecodeError::MULTI_TOO_FEW_ARGS)) + } + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs index 44293133d2..28fd6e3943 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_payload.rs @@ -40,6 +40,15 @@ where _phantom: PhantomData, } } + + pub(crate) fn remaining(&self) -> usize { + (self.byte_end - self.byte_start) / P::payload_size() + } + + /// TODO: can be replaced with ExactSizeIterator::is_empty once it's stabilized + pub(crate) fn iter_is_empty(&self) -> bool { + self.byte_start >= self.byte_end + } } impl Iterator for ManagedVecPayloadIterator @@ -50,10 +59,10 @@ where type Item = P; fn next(&mut self) -> Option

{ - let next_byte_start = self.byte_start + P::payload_size(); - if next_byte_start > self.byte_end { + if self.iter_is_empty() { return None; } + let next_byte_start = self.byte_start + P::payload_size(); let mut payload = P::new_buffer(); let _ = M::managed_type_impl().mb_load_slice( @@ -67,8 +76,7 @@ where } fn size_hint(&self) -> (usize, Option) { - let size = P::payload_size(); - let remaining = (self.byte_end - self.byte_start) / size; + let remaining = self.remaining(); (remaining, Some(remaining)) } } @@ -78,6 +86,9 @@ where M: ManagedTypeApi, P: ManagedVecItemPayload, { + fn len(&self) -> usize { + self.remaining() + } } impl DoubleEndedIterator for ManagedVecPayloadIterator @@ -86,7 +97,7 @@ where P: ManagedVecItemPayload, { fn next_back(&mut self) -> Option { - if self.byte_start + P::payload_size() > self.byte_end { + if self.iter_is_empty() { return None; } self.byte_end -= P::payload_size(); diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs index b57a16d3d7..7305462b1c 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs @@ -1,6 +1,11 @@ use core::marker::PhantomData; -use crate::{api::ManagedTypeApi, types::ManagedType}; +use multiversx_sc_codec::{DecodeError, DecodeErrorHandler, TopDecodeMultiInput}; + +use crate::{ + api::{ErrorApi, ManagedTypeApi}, + types::{ManagedBuffer, ManagedType}, +}; use super::{ManagedVec, ManagedVecItem, ManagedVecPayloadIterator}; @@ -38,6 +43,10 @@ where } } } + + pub(crate) fn iter_is_empty(&self) -> bool { + self.payload_iter.iter_is_empty() + } } impl<'a, M, T> Iterator for ManagedVecRefIterator<'a, M, T> @@ -89,3 +98,25 @@ where } } } + +impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer> +where + A: ManagedTypeApi + ErrorApi, +{ + type ValueInput = ManagedBuffer; + + fn has_next(&self) -> bool { + !self.iter_is_empty() + } + + fn next_value_input(&mut self, h: H) -> Result + where + H: DecodeErrorHandler, + { + if let Some(buffer) = self.next() { + Ok(buffer.clone()) + } else { + Err(h.handle_error(DecodeError::MULTI_TOO_FEW_ARGS)) + } + } +} From 2e776b7b56f1a579fc776294d1bb2612d02103be Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 11 Dec 2024 20:41:15 +0200 Subject: [PATCH 084/133] clippy fix --- .../base/src/types/managed/wrapped/managed_vec_iter_ref.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs index 7305462b1c..ae5212c9d5 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs @@ -99,7 +99,7 @@ where } } -impl<'a, A> TopDecodeMultiInput for ManagedVecRefIterator<'a, A, ManagedBuffer> +impl TopDecodeMultiInput for ManagedVecRefIterator<'_, A, ManagedBuffer> where A: ManagedTypeApi + ErrorApi, { From 7955fcc41e3c9e6c07b12a439907607458534a23 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 11 Dec 2024 20:41:43 +0200 Subject: [PATCH 085/133] refactor: ManagedResultArgLoader replaced in legacy callback --- framework/base/src/types/interaction/callback_closure.rs | 7 +++---- framework/derive/src/generate/method_call_gen_arg.rs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/framework/base/src/types/interaction/callback_closure.rs b/framework/base/src/types/interaction/callback_closure.rs index 6b2b73feee..b7ea4264a8 100644 --- a/framework/base/src/types/interaction/callback_closure.rs +++ b/framework/base/src/types/interaction/callback_closure.rs @@ -9,10 +9,9 @@ use crate::{ }, contract_base::{BlockchainWrapper, ExitCodecErrorHandler, ManagedSerializer}, err_msg, - io::ManagedResultArgLoader, storage::StorageKey, storage_clear, storage_get, storage_set, - types::{ManagedBuffer, ManagedType}, + types::{ManagedBuffer, ManagedType, ManagedVecRefIterator}, }; use super::ManagedArgBuffer; @@ -125,8 +124,8 @@ impl CallbackClosureForDeser { CallbackClosureMatcher::new(&self.callback_name) } - pub fn into_arg_loader(self) -> ManagedResultArgLoader { - ManagedResultArgLoader::new(self.closure_args.data) + pub fn arg_iter(&self) -> ManagedVecRefIterator<'_, M, ManagedBuffer> { + self.closure_args.iter_buffers() } } diff --git a/framework/derive/src/generate/method_call_gen_arg.rs b/framework/derive/src/generate/method_call_gen_arg.rs index 20550ca024..8c9b7a0aee 100644 --- a/framework/derive/src/generate/method_call_gen_arg.rs +++ b/framework/derive/src/generate/method_call_gen_arg.rs @@ -88,7 +88,7 @@ pub fn load_legacy_cb_closure_args_snippet(m: &Method) -> proc_macro2::TokenStre }); quote! { let #closure_var_names = multiversx_sc::io::load_multi_args_custom_loader::( - ___cb_closure___.into_arg_loader(), + ___cb_closure___.arg_iter(), #closure_var_names_str, ); } From d74aa6add2e85e36adb924da075b2ebd9a3ac4df Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 11 Dec 2024 21:08:42 +0200 Subject: [PATCH 086/133] simplified callback_selector --- .../interaction/callback_selector_result.rs | 18 ++++----- framework/derive/src/contract_impl.rs | 4 +- framework/derive/src/generate/callback_gen.rs | 18 +++------ .../scenario/tests/contract_without_macros.rs | 39 ++++++------------- 4 files changed, 30 insertions(+), 49 deletions(-) diff --git a/framework/base/src/types/interaction/callback_selector_result.rs b/framework/base/src/types/interaction/callback_selector_result.rs index d04487b57f..e6bd200a66 100644 --- a/framework/base/src/types/interaction/callback_selector_result.rs +++ b/framework/base/src/types/interaction/callback_selector_result.rs @@ -1,13 +1,13 @@ -use crate::api::{ErrorApi, ManagedTypeApi}; - -use super::CallbackClosureForDeser; - /// Used internally between the `callback` and `callback_selector` methods. /// It is likely to be removed in the future. -pub enum CallbackSelectorResult -where - A: ManagedTypeApi + ErrorApi, -{ +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum CallbackSelectorResult { Processed, - NotProcessed(CallbackClosureForDeser), + NotProcessed, +} + +impl CallbackSelectorResult { + pub fn is_processed(self) -> bool { + matches!(self, CallbackSelectorResult::Processed) + } } diff --git a/framework/derive/src/contract_impl.rs b/framework/derive/src/contract_impl.rs index b10d66d3ad..32ee2d76e0 100644 --- a/framework/derive/src/contract_impl.rs +++ b/framework/derive/src/contract_impl.rs @@ -79,7 +79,9 @@ pub fn contract_implementation( #function_selector_body } - fn callback_selector(&mut self, mut ___cb_closure___: multiversx_sc::types::CallbackClosureForDeser) -> multiversx_sc::types::CallbackSelectorResult { + fn callback_selector(&mut self, ___cb_closure___: &multiversx_sc::types::CallbackClosureForDeser) + -> multiversx_sc::types::CallbackSelectorResult + { #callback_selector_body } diff --git a/framework/derive/src/generate/callback_gen.rs b/framework/derive/src/generate/callback_gen.rs index 23a3a56713..e16e6daafa 100644 --- a/framework/derive/src/generate/callback_gen.rs +++ b/framework/derive/src/generate/callback_gen.rs @@ -29,7 +29,7 @@ pub fn generate_callback_selector_and_main( let cb_main_body = quote! { let _ = self::EndpointWrappers::callback_selector( self, - multiversx_sc::types::CallbackClosureForDeser::no_callback(), + &multiversx_sc::types::CallbackClosureForDeser::no_callback(), ); }; (cb_selector_body, cb_main_body) @@ -39,7 +39,7 @@ pub fn generate_callback_selector_and_main( module_calls(contract.supertraits.as_slice()); if match_arms.is_empty() && module_calls.is_empty() { let cb_selector_body = quote! { - multiversx_sc::types::CallbackSelectorResult::NotProcessed(___cb_closure___) + multiversx_sc::types::CallbackSelectorResult::NotProcessed }; let cb_main_body = quote! {}; (cb_selector_body, cb_main_body) @@ -47,8 +47,7 @@ pub fn generate_callback_selector_and_main( let cb_selector_body = callback_selector_body(match_arms, module_calls); let cb_main_body = quote! { if let Some(___cb_closure___) = multiversx_sc::types::CallbackClosureForDeser::storage_load_and_clear::() { - if let multiversx_sc::types::CallbackSelectorResult::NotProcessed(_) = - self::EndpointWrappers::callback_selector(self, ___cb_closure___) { + if !self::EndpointWrappers::callback_selector(self, &___cb_closure___).is_processed() { multiversx_sc::api::ErrorApiImpl::signal_error( &::error_api_impl(), err_msg::CALLBACK_BAD_FUNC.as_bytes(), @@ -79,7 +78,7 @@ fn callback_selector_body( } #(#match_arms)* #(#module_calls)* - multiversx_sc::types::CallbackSelectorResult::NotProcessed(___cb_closure___) + multiversx_sc::types::CallbackSelectorResult::NotProcessed } } @@ -123,13 +122,8 @@ pub fn module_calls(supertraits: &[Supertrait]) -> Vec .map(|supertrait| { let module_path = &supertrait.module_path; quote! { - match #module_path EndpointWrappers::callback_selector(self, ___cb_closure___) { - multiversx_sc::types::CallbackSelectorResult::Processed => { - return multiversx_sc::types::CallbackSelectorResult::Processed; - }, - multiversx_sc::types::CallbackSelectorResult::NotProcessed(recovered_cb_closure) => { - ___cb_closure___ = recovered_cb_closure; - }, + if #module_path EndpointWrappers::callback_selector(self, ___cb_closure___).is_processed() { + return multiversx_sc::types::CallbackSelectorResult::Processed; } } }) diff --git a/framework/scenario/tests/contract_without_macros.rs b/framework/scenario/tests/contract_without_macros.rs index d461adea6d..29189bf898 100644 --- a/framework/scenario/tests/contract_without_macros.rs +++ b/framework/scenario/tests/contract_without_macros.rs @@ -83,9 +83,9 @@ mod module_1 { } fn callback_selector( &mut self, - mut ___cb_closure___: multiversx_sc::types::CallbackClosureForDeser, - ) -> multiversx_sc::types::CallbackSelectorResult { - multiversx_sc::types::CallbackSelectorResult::NotProcessed(___cb_closure___) + ___cb_closure___: &multiversx_sc::types::CallbackClosureForDeser, + ) -> multiversx_sc::types::CallbackSelectorResult { + multiversx_sc::types::CallbackSelectorResult::NotProcessed } } @@ -357,40 +357,25 @@ mod sample_adder { } fn callback_selector( &mut self, - mut ___cb_closure___: multiversx_sc::types::CallbackClosureForDeser, - ) -> multiversx_sc::types::CallbackSelectorResult { + ___cb_closure___: &multiversx_sc::types::CallbackClosureForDeser, + ) -> multiversx_sc::types::CallbackSelectorResult { let ___cb_closure_matcher___ = ___cb_closure___.matcher::<32usize>(); if ___cb_closure_matcher___.matches_empty() { return multiversx_sc::types::CallbackSelectorResult::Processed; } - match super::module_1::EndpointWrappers::callback_selector(self, ___cb_closure___) { - multiversx_sc::types::CallbackSelectorResult::Processed => { - return multiversx_sc::types::CallbackSelectorResult::Processed; - }, - multiversx_sc::types::CallbackSelectorResult::NotProcessed( - recovered_cb_closure, - ) => { - ___cb_closure___ = recovered_cb_closure; - }, - } - match super::module_1::EndpointWrappers::callback_selector(self, ___cb_closure___) { - multiversx_sc::types::CallbackSelectorResult::Processed => { - return multiversx_sc::types::CallbackSelectorResult::Processed; - }, - multiversx_sc::types::CallbackSelectorResult::NotProcessed( - recovered_cb_closure, - ) => { - ___cb_closure___ = recovered_cb_closure; - }, + if super::module_1::EndpointWrappers::callback_selector(self, ___cb_closure___) + .is_processed() + { + return multiversx_sc::types::CallbackSelectorResult::Processed; } - multiversx_sc::types::CallbackSelectorResult::NotProcessed(___cb_closure___) + multiversx_sc::types::CallbackSelectorResult::NotProcessed } fn callback(&mut self) { if let Some(___cb_closure___) = multiversx_sc::types::CallbackClosureForDeser::storage_load_and_clear::() { - if let multiversx_sc::types::CallbackSelectorResult::NotProcessed(_) = - self::EndpointWrappers::callback_selector(self, ___cb_closure___) + if !self::EndpointWrappers::callback_selector(self, &___cb_closure___) + .is_processed() { multiversx_sc::api::ErrorApiImpl::signal_error( &::error_api_impl(), From eedd7f2c2a198248b276e0761442aacb98e17666 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 11 Dec 2024 21:23:42 +0200 Subject: [PATCH 087/133] refactor: ManagedResultArgLoader removed from load_callback_closure_args --- framework/base/src/io/arg_nested_tuple.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/framework/base/src/io/arg_nested_tuple.rs b/framework/base/src/io/arg_nested_tuple.rs index 1a0eaace7a..aa833633d8 100644 --- a/framework/base/src/io/arg_nested_tuple.rs +++ b/framework/base/src/io/arg_nested_tuple.rs @@ -1,15 +1,15 @@ use unwrap_infallible::UnwrapInfallible; -use super::{EndpointDynArgLoader, EndpointSingleArgLoader, ManagedResultArgLoader}; +use super::{EndpointDynArgLoader, EndpointSingleArgLoader}; use crate::{ api::{ - const_handles, use_raw_handle, EndpointArgumentApi, EndpointArgumentApiImpl, ErrorApi, - ErrorApiImpl, ManagedTypeApi, StaticVarApiImpl, VMApi, + const_handles, EndpointArgumentApi, EndpointArgumentApiImpl, ErrorApi, ErrorApiImpl, + ManagedTypeApi, StaticVarApiImpl, VMApi, }, codec::{DecodeError, TopDecodeMulti, TopDecodeMultiInput}, err_msg, io::{ArgErrorHandler, ArgId}, - types::{ManagedArgBuffer, ManagedBuffer, ManagedType}, + types::{ManagedArgBuffer, ManagedBuffer, ManagedType, ManagedVecRefIterator}, }; /// Argument count cannot change during execution, and it can get queried multiple times, @@ -194,19 +194,16 @@ where N::next_multi_arg(loader, arg_names) } -fn callback_closure_args_loader() -> ManagedResultArgLoader +fn callback_closure_args_loader() -> ManagedVecRefIterator<'static, AA, ManagedBuffer> where AA: VMApi, { + let cb_closure_args_serialized = ManagedBuffer::::new(); + AA::argument_api_impl().load_callback_closure_buffer(cb_closure_args_serialized.get_handle()); unsafe { - AA::argument_api_impl() - .load_callback_closure_buffer(use_raw_handle(const_handles::MBUF_TEMPORARY_1)); - let cb_closure_args_serialized = - ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); let mut cb_closure_args_buffer = ManagedArgBuffer::::from_raw_handle(const_handles::CALLBACK_CLOSURE_ARGS_BUFFER); cb_closure_args_buffer.deserialize_overwrite(cb_closure_args_serialized); - - ManagedResultArgLoader::new(cb_closure_args_buffer.into_vec_of_buffers()) + ManagedVecRefIterator::new_from_handle(cb_closure_args_buffer.forget_into_handle()) } } From 806aa3f6b359577d31716f40fa6de7b413889282 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 11 Dec 2024 21:23:55 +0200 Subject: [PATCH 088/133] removed ManagedResultArgLoader --- framework/base/src/io.rs | 2 - .../base/src/io/managed_result_arg_loader.rs | 52 ------------------- .../managed/wrapped/managed_vec_iter_ref.rs | 8 ++- 3 files changed, 6 insertions(+), 56 deletions(-) delete mode 100644 framework/base/src/io/managed_result_arg_loader.rs diff --git a/framework/base/src/io.rs b/framework/base/src/io.rs index be7f4444f6..7d71dd2e27 100644 --- a/framework/base/src/io.rs +++ b/framework/base/src/io.rs @@ -7,7 +7,6 @@ mod arg_nested_tuple; mod bytes_arg_loader; pub mod call_value_init; mod finish; -mod managed_result_arg_loader; mod signal_error; pub use arg_de_input::*; @@ -18,5 +17,4 @@ use arg_loader_single::*; pub use arg_nested_tuple::*; pub use bytes_arg_loader::*; pub use finish::*; -pub use managed_result_arg_loader::*; pub use signal_error::*; diff --git a/framework/base/src/io/managed_result_arg_loader.rs b/framework/base/src/io/managed_result_arg_loader.rs deleted file mode 100644 index 77bc9967e1..0000000000 --- a/framework/base/src/io/managed_result_arg_loader.rs +++ /dev/null @@ -1,52 +0,0 @@ -use crate::codec::{DecodeError, DecodeErrorHandler, TopDecodeMultiInput}; - -use crate::{ - api::{ErrorApi, ManagedTypeApi}, - types::{ManagedBuffer, ManagedVec}, -}; - -pub struct ManagedResultArgLoader -where - A: ManagedTypeApi + ErrorApi, -{ - data: ManagedVec>, - data_len: usize, - next_index: usize, -} - -impl ManagedResultArgLoader -where - A: ManagedTypeApi + ErrorApi, -{ - pub fn new(data: ManagedVec>) -> Self { - let data_len = data.len(); - ManagedResultArgLoader { - data, - data_len, - next_index: 0, - } - } -} - -impl TopDecodeMultiInput for ManagedResultArgLoader -where - A: ManagedTypeApi + ErrorApi, -{ - type ValueInput = ManagedBuffer; - - fn has_next(&self) -> bool { - self.next_index < self.data_len - } - - fn next_value_input(&mut self, h: H) -> Result - where - H: DecodeErrorHandler, - { - if let Some(buffer) = self.data.try_get(self.next_index) { - self.next_index += 1; - Ok((*buffer).clone()) - } else { - Err(h.handle_error(DecodeError::MULTI_TOO_FEW_ARGS)) - } - } -} diff --git a/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs b/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs index ae5212c9d5..f48e3ecab1 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_iter_ref.rs @@ -35,15 +35,19 @@ where M: ManagedTypeApi, T: ManagedVecItem, { - pub(crate) fn new(managed_vec: &'a ManagedVec) -> Self { + pub(crate) unsafe fn new_from_handle(vec_handle: M::ManagedBufferHandle) -> Self { unsafe { ManagedVecRefIterator { - payload_iter: ManagedVecPayloadIterator::new(managed_vec.get_handle()), + payload_iter: ManagedVecPayloadIterator::new(vec_handle), _phantom: PhantomData, } } } + pub(crate) fn new(managed_vec: &'a ManagedVec) -> Self { + unsafe { ManagedVecRefIterator::new_from_handle(managed_vec.get_handle()) } + } + pub(crate) fn iter_is_empty(&self) -> bool { self.payload_iter.iter_is_empty() } From f84bbd7e3b105d2aa607b83864cdb5ccafbd73aa Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Thu, 12 Dec 2024 15:21:54 +0200 Subject: [PATCH 089/133] code report - show diff size in report --- framework/meta/src/cmd/code_report/compare.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/framework/meta/src/cmd/code_report/compare.rs b/framework/meta/src/cmd/code_report/compare.rs index 28c604962d..98f64c7738 100644 --- a/framework/meta/src/cmd/code_report/compare.rs +++ b/framework/meta/src/cmd/code_report/compare.rs @@ -1,10 +1,20 @@ pub(crate) fn size_status_after_comparing(size: usize, compared_size: usize) -> String { match size.cmp(&compared_size) { std::cmp::Ordering::Greater => { - format!("{} :arrow_right: {} :red_circle:", compared_size, size) + format!( + "{} :arrow_right: {} :red_circle: (+{})", + compared_size, + size, + size - compared_size + ) }, std::cmp::Ordering::Less => { - format!("{} :arrow_right: {} :green_circle:", compared_size, size) + format!( + "{} :arrow_right: {} :green_circle: (-{})", + compared_size, + size, + compared_size - size + ) }, std::cmp::Ordering::Equal => { format!("{}", size) From 96a414af84aa2f12b1e8646432ec909e518d1928 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 12 Dec 2024 16:34:02 +0200 Subject: [PATCH 090/133] ContractObj wraps UniversalContractObj --- framework/derive/src/generate/snippets.rs | 20 +++++++------------ .../scenario/tests/contract_without_macros.rs | 17 ++++++---------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/framework/derive/src/generate/snippets.rs b/framework/derive/src/generate/snippets.rs index 91fc8a863f..64c590ad5f 100644 --- a/framework/derive/src/generate/snippets.rs +++ b/framework/derive/src/generate/snippets.rs @@ -1,11 +1,8 @@ pub fn contract_object_def() -> proc_macro2::TokenStream { quote! { - pub struct ContractObj - where - A: multiversx_sc::api::VMApi, - { - _phantom: core::marker::PhantomData, - } + pub struct ContractObj(multiversx_sc::contract_base::UniversalContractObj) + where + A: multiversx_sc::api::VMApi; } } @@ -26,9 +23,7 @@ pub fn new_contract_object_fn() -> proc_macro2::TokenStream { where A: multiversx_sc::api::VMApi, { - ContractObj { - _phantom: core::marker::PhantomData, - } + ContractObj::(multiversx_sc::contract_base::UniversalContractObj::::new()) } pub struct ContractBuilder; @@ -36,10 +31,9 @@ pub fn new_contract_object_fn() -> proc_macro2::TokenStream { impl multiversx_sc::contract_base::CallableContractBuilder for self::ContractBuilder { fn new_contract_obj( &self, - ) -> multiversx_sc::types::heap::Box { - multiversx_sc::types::heap::Box::new(ContractObj:: { - _phantom: core::marker::PhantomData, - }) + ) -> multiversx_sc::types::heap::Box + { + multiversx_sc::types::heap::Box::new(self::contract_obj::()) } } } diff --git a/framework/scenario/tests/contract_without_macros.rs b/framework/scenario/tests/contract_without_macros.rs index 29189bf898..d0da5fac52 100644 --- a/framework/scenario/tests/contract_without_macros.rs +++ b/framework/scenario/tests/contract_without_macros.rs @@ -592,12 +592,9 @@ mod sample_adder { ///////////////////////////////////////////////////////////////////////////////////////////////// //////// CONTRACT OBJECT //////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// - pub struct ContractObj + pub struct ContractObj(multiversx_sc::contract_base::UniversalContractObj) where - A: multiversx_sc::api::VMApi, - { - _phantom: core::marker::PhantomData, - } + A: multiversx_sc::api::VMApi; ///////////////////////////////////////////////////////////////////////////////////////////////// //////// CONTRACT OBJECT as CONTRACT BASE /////////////////////////////////////////////////////// @@ -633,19 +630,17 @@ mod sample_adder { where A: multiversx_sc::api::VMApi, { - ContractObj { - _phantom: core::marker::PhantomData, - } + ContractObj::(multiversx_sc::contract_base::UniversalContractObj::::new()) } + pub struct ContractBuilder; + impl multiversx_sc::contract_base::CallableContractBuilder for self::ContractBuilder { fn new_contract_obj( &self, ) -> multiversx_sc::types::heap::Box { - multiversx_sc::types::heap::Box::new(ContractObj:: { - _phantom: core::marker::PhantomData, - }) + multiversx_sc::types::heap::Box::new(self::contract_obj::()) } } From 52302401391fdb07c489abde11e13f446c8e1532 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 13 Dec 2024 21:31:45 +0200 Subject: [PATCH 091/133] static api - initialization flags grouped into single bitfield --- framework/base/src/api/managed_types.rs | 2 + .../src/api/managed_types/static_var_api.rs | 18 ++++++- .../api/managed_types/static_var_api_flags.rs | 53 +++++++++++++++++++ .../uncallable/static_var_api_uncallable.rs | 10 +++- .../wrappers/call_value_wrapper.rs | 22 ++++---- .../src/api/local_api_vh/static_var_api_vh.rs | 12 ++++- .../src/debug_executor/tx_static_vars.rs | 7 ++- .../api/managed_types/static_var_api_node.rs | 13 ++++- 8 files changed, 119 insertions(+), 18 deletions(-) create mode 100644 framework/base/src/api/managed_types/static_var_api_flags.rs diff --git a/framework/base/src/api/managed_types.rs b/framework/base/src/api/managed_types.rs index 3562020b95..1322ede5ee 100644 --- a/framework/base/src/api/managed_types.rs +++ b/framework/base/src/api/managed_types.rs @@ -8,6 +8,7 @@ mod managed_map_api; mod managed_type_api; mod managed_type_api_impl; mod static_var_api; +mod static_var_api_flags; mod token_identifier_util; pub use big_float_api::*; @@ -19,3 +20,4 @@ pub use managed_map_api::*; pub use managed_type_api::*; pub use managed_type_api_impl::*; pub use static_var_api::*; +pub use static_var_api_flags::StaticVarApiFlags; diff --git a/framework/base/src/api/managed_types/static_var_api.rs b/framework/base/src/api/managed_types/static_var_api.rs index 8eaf474ef3..8fd007d648 100644 --- a/framework/base/src/api/managed_types/static_var_api.rs +++ b/framework/base/src/api/managed_types/static_var_api.rs @@ -1,6 +1,6 @@ use crate::types::LockableStaticBuffer; -use super::RawHandle; +use super::{RawHandle, StaticVarApiFlags}; pub trait StaticVarApi { type StaticVarApiImpl: StaticVarApiImpl; @@ -24,6 +24,22 @@ pub trait StaticVarApiImpl { fn get_num_arguments(&self) -> i32; + fn set_flags(&self, flags: StaticVarApiFlags); + + fn get_flags(&self) -> StaticVarApiFlags; + + /// Returns true if the flag is set, false if is default (false). + /// + /// If the flag is unset (false), will set it. + fn flag_is_set_or_update(&self, flag: StaticVarApiFlags) -> bool { + let mut current_flags = self.get_flags(); + let contains_flag = current_flags.check_and_set(flag); + if !contains_flag { + self.set_flags(current_flags); + } + contains_flag + } + fn set_call_value_egld_handle(&self, handle: RawHandle); fn get_call_value_egld_handle(&self) -> RawHandle; diff --git a/framework/base/src/api/managed_types/static_var_api_flags.rs b/framework/base/src/api/managed_types/static_var_api_flags.rs new file mode 100644 index 0000000000..1c9e153e69 --- /dev/null +++ b/framework/base/src/api/managed_types/static_var_api_flags.rs @@ -0,0 +1,53 @@ +use bitflags::bitflags; + +bitflags! { + #[derive(Clone, Copy, Debug, PartialEq, Eq)] + pub struct StaticVarApiFlags: u8 { + const NONE = 0b00000000; + const CALL_VALUE_EGLD_INITIALIZED = 0b00000001; + const CALL_VALUE_EGLD_MULTI_INITIALIZED = 0b00000010; + const CALL_VALUE_MULTI_ESDT_INITIALIZED = 0b00000100; + const CALL_VALUE_ALL_INITIALIZED = 0b00001000; + } +} + +impl StaticVarApiFlags { + pub fn check_and_set(&mut self, other: StaticVarApiFlags) -> bool { + let contains_flag = self.contains(other); + if !contains_flag { + *self |= other; + } + contains_flag + } +} + +#[cfg(test)] +pub mod tests { + use super::StaticVarApiFlags; + + #[test] + fn test_check_and_set() { + let mut current = StaticVarApiFlags::NONE; + + assert!(current.check_and_set(StaticVarApiFlags::NONE)); + assert_eq!(current, StaticVarApiFlags::NONE); + + assert!(!current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED)); + assert_eq!(current, StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED); + assert!(current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED)); + assert_eq!(current, StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED); + + assert!(!current.check_and_set(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED)); + assert_eq!( + current, + StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED + | StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED + ); + assert!(current.check_and_set(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED)); + assert_eq!( + current, + StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED + | StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED + ); + } +} diff --git a/framework/base/src/api/uncallable/static_var_api_uncallable.rs b/framework/base/src/api/uncallable/static_var_api_uncallable.rs index 1da3c772cf..db126b337d 100644 --- a/framework/base/src/api/uncallable/static_var_api_uncallable.rs +++ b/framework/base/src/api/uncallable/static_var_api_uncallable.rs @@ -1,5 +1,5 @@ use crate::{ - api::{RawHandle, StaticVarApi, StaticVarApiImpl}, + api::{RawHandle, StaticVarApi, StaticVarApiFlags, StaticVarApiImpl}, types::LockableStaticBuffer, }; @@ -41,6 +41,14 @@ impl StaticVarApiImpl for UncallableApi { unreachable!() } + fn set_flags(&self, _flags: StaticVarApiFlags) { + unreachable!() + } + + fn get_flags(&self) -> StaticVarApiFlags { + unreachable!() + } + fn set_call_value_egld_handle(&self, _handle: RawHandle) { unreachable!() } diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 3fb85e1658..1edb635a9d 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -3,7 +3,7 @@ use core::marker::PhantomData; use crate::{ api::{ const_handles, use_raw_handle, CallValueApi, CallValueApiImpl, ErrorApi, ErrorApiImpl, - HandleConstraints, ManagedTypeApi, StaticVarApiImpl, + ManagedTypeApi, StaticVarApiFlags, StaticVarApiImpl, }, err_msg, types::{ @@ -34,11 +34,10 @@ where /// Retrieves the EGLD call value from the VM. /// Will return 0 in case of an ESDT transfer (cannot have both EGLD and ESDT transfer simultaneously). pub fn egld_value(&self) -> ManagedRef<'static, A, BigUint> { - let mut call_value_handle: A::BigIntHandle = - use_raw_handle(A::static_var_api_impl().get_call_value_egld_handle()); - if call_value_handle == const_handles::UNINITIALIZED_HANDLE { - call_value_handle = use_raw_handle(const_handles::CALL_VALUE_EGLD); - A::static_var_api_impl().set_call_value_egld_handle(call_value_handle.get_raw_handle()); + let call_value_handle: A::BigIntHandle = use_raw_handle(const_handles::CALL_VALUE_EGLD); + if !A::static_var_api_impl() + .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED) + { A::call_value_api_impl().load_egld_value(call_value_handle.clone()); } unsafe { ManagedRef::wrap_handle(call_value_handle) } @@ -55,12 +54,11 @@ where /// Will return 0 results if nothing was transfered, or just EGLD. /// Fully managed underlying types, very efficient. pub fn all_esdt_transfers(&self) -> ManagedRef<'static, A, ManagedVec>> { - let mut call_value_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().get_call_value_multi_esdt_handle()); - if call_value_handle == const_handles::UNINITIALIZED_HANDLE { - call_value_handle = use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT); - A::static_var_api_impl() - .set_call_value_multi_esdt_handle(call_value_handle.get_raw_handle()); + let call_value_handle: A::ManagedBufferHandle = + use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT); + if !A::static_var_api_impl() + .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_MULTI_ESDT_INITIALIZED) + { A::call_value_api_impl().load_all_esdt_transfers(call_value_handle.clone()); } unsafe { ManagedRef::wrap_handle(call_value_handle) } diff --git a/framework/scenario/src/api/local_api_vh/static_var_api_vh.rs b/framework/scenario/src/api/local_api_vh/static_var_api_vh.rs index e72ae45f74..07bef47bda 100644 --- a/framework/scenario/src/api/local_api_vh/static_var_api_vh.rs +++ b/framework/scenario/src/api/local_api_vh/static_var_api_vh.rs @@ -1,6 +1,6 @@ use crate::api::{VMHooksApi, VMHooksApiBackend}; use multiversx_sc::{ - api::{use_raw_handle, RawHandle, StaticVarApi, StaticVarApiImpl}, + api::{use_raw_handle, RawHandle, StaticVarApi, StaticVarApiFlags, StaticVarApiImpl}, types::LockableStaticBuffer, }; @@ -55,6 +55,16 @@ impl StaticVarApiImpl for VMHooksApi { self.with_static_data(|data| data.static_vars_cell.borrow().num_arguments) } + fn set_flags(&self, flags: StaticVarApiFlags) { + self.with_static_data(|data| { + data.static_vars_cell.borrow_mut().flags = flags; + }) + } + + fn get_flags(&self) -> StaticVarApiFlags { + self.with_static_data(|data| data.static_vars_cell.borrow().flags) + } + fn set_call_value_egld_handle(&self, handle: RawHandle) { self.with_static_data(|data| { data.static_vars_cell.borrow_mut().call_value_egld_handle = handle; diff --git a/framework/scenario/src/debug_executor/tx_static_vars.rs b/framework/scenario/src/debug_executor/tx_static_vars.rs index 88277694c4..bca543d8ba 100644 --- a/framework/scenario/src/debug_executor/tx_static_vars.rs +++ b/framework/scenario/src/debug_executor/tx_static_vars.rs @@ -1,13 +1,15 @@ -use multiversx_sc::api::{const_handles, RawHandle}; +use multiversx_sc::api::{const_handles, RawHandle, StaticVarApiFlags}; #[derive(Debug)] pub struct TxStaticVars { pub external_view_target_address_handle: RawHandle, pub next_handle: RawHandle, pub num_arguments: i32, + pub flags: StaticVarApiFlags, pub call_value_egld_handle: RawHandle, pub call_value_multi_esdt_handle: RawHandle, - //vec of true/false, true if bit from handle = scaling_start + index is not empty + + /// Vec of true/false, true if bit from handle = scaling_start + index is not empty pub scaling_factor_init: [bool; const_handles::SCALING_FACTOR_LENGTH], } @@ -20,6 +22,7 @@ impl Default for TxStaticVars { call_value_egld_handle: const_handles::UNINITIALIZED_HANDLE, call_value_multi_esdt_handle: const_handles::UNINITIALIZED_HANDLE, scaling_factor_init: [false; const_handles::SCALING_FACTOR_LENGTH], + flags: StaticVarApiFlags::NONE, } } } diff --git a/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs b/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs index 501d53d68f..b282449c94 100644 --- a/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs +++ b/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs @@ -1,5 +1,5 @@ use multiversx_sc::{ - api::{const_handles, RawHandle, StaticVarApi, StaticVarApiImpl}, + api::{const_handles, RawHandle, StaticVarApi, StaticVarApiFlags, StaticVarApiImpl}, types::LockableStaticBuffer, }; @@ -9,6 +9,7 @@ static mut STATIC_BUFFER: LockableStaticBuffer = LockableStaticBuffer::new(); static mut EXTERNAL_VIEW_TARGET_ADDRESS_HANDLE: i32 = 0; static mut NEXT_HANDLE: i32 = const_handles::NEW_HANDLE_START_FROM; static mut NUM_ARGUMENTS: i32 = 0; +static mut FLAGS: StaticVarApiFlags = StaticVarApiFlags::NONE; static mut CALL_VALUE_EGLD_HANDLE: i32 = const_handles::UNINITIALIZED_HANDLE; static mut CALL_VALUE_MULTI_ESDT_HANDLE: i32 = const_handles::UNINITIALIZED_HANDLE; static mut SCALING_FACTOR_INIT: [bool; const_handles::SCALING_FACTOR_LENGTH] = @@ -62,6 +63,16 @@ impl StaticVarApiImpl for VmApiImpl { unsafe { NUM_ARGUMENTS } } + fn set_flags(&self, flags: StaticVarApiFlags) { + unsafe { + FLAGS = flags; + } + } + + fn get_flags(&self) -> StaticVarApiFlags { + unsafe { FLAGS } + } + fn set_call_value_egld_handle(&self, handle: RawHandle) { unsafe { CALL_VALUE_EGLD_HANDLE = handle; From de2c6302d11ebe2c1cdd9dc25bf8bae863f3e964 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sat, 14 Dec 2024 05:28:13 +0200 Subject: [PATCH 092/133] static api - removing old call value handle fields --- .../src/api/managed_types/static_var_api.rs | 8 ------ .../uncallable/static_var_api_uncallable.rs | 16 ----------- .../src/api/local_api_vh/static_var_api_vh.rs | 28 +------------------ .../src/debug_executor/tx_static_vars.rs | 4 --- .../api/managed_types/static_var_api_node.rs | 22 --------------- 5 files changed, 1 insertion(+), 77 deletions(-) diff --git a/framework/base/src/api/managed_types/static_var_api.rs b/framework/base/src/api/managed_types/static_var_api.rs index 8fd007d648..9044cd6b06 100644 --- a/framework/base/src/api/managed_types/static_var_api.rs +++ b/framework/base/src/api/managed_types/static_var_api.rs @@ -40,14 +40,6 @@ pub trait StaticVarApiImpl { contains_flag } - fn set_call_value_egld_handle(&self, handle: RawHandle); - - fn get_call_value_egld_handle(&self) -> RawHandle; - - fn set_call_value_multi_esdt_handle(&self, handle: RawHandle); - - fn get_call_value_multi_esdt_handle(&self) -> RawHandle; - fn is_scaling_factor_cached(&self, decimals: usize) -> bool; fn set_scaling_factor_cached(&self, decimals: usize); diff --git a/framework/base/src/api/uncallable/static_var_api_uncallable.rs b/framework/base/src/api/uncallable/static_var_api_uncallable.rs index db126b337d..005a302e53 100644 --- a/framework/base/src/api/uncallable/static_var_api_uncallable.rs +++ b/framework/base/src/api/uncallable/static_var_api_uncallable.rs @@ -49,22 +49,6 @@ impl StaticVarApiImpl for UncallableApi { unreachable!() } - fn set_call_value_egld_handle(&self, _handle: RawHandle) { - unreachable!() - } - - fn get_call_value_egld_handle(&self) -> RawHandle { - unreachable!() - } - - fn set_call_value_multi_esdt_handle(&self, _handle: RawHandle) { - unreachable!() - } - - fn get_call_value_multi_esdt_handle(&self) -> RawHandle { - unreachable!() - } - fn is_scaling_factor_cached(&self, _decimals: usize) -> bool { unreachable!() } diff --git a/framework/scenario/src/api/local_api_vh/static_var_api_vh.rs b/framework/scenario/src/api/local_api_vh/static_var_api_vh.rs index 07bef47bda..903094279e 100644 --- a/framework/scenario/src/api/local_api_vh/static_var_api_vh.rs +++ b/framework/scenario/src/api/local_api_vh/static_var_api_vh.rs @@ -1,6 +1,6 @@ use crate::api::{VMHooksApi, VMHooksApiBackend}; use multiversx_sc::{ - api::{use_raw_handle, RawHandle, StaticVarApi, StaticVarApiFlags, StaticVarApiImpl}, + api::{RawHandle, StaticVarApi, StaticVarApiFlags, StaticVarApiImpl}, types::LockableStaticBuffer, }; @@ -65,32 +65,6 @@ impl StaticVarApiImpl for VMHooksApi { self.with_static_data(|data| data.static_vars_cell.borrow().flags) } - fn set_call_value_egld_handle(&self, handle: RawHandle) { - self.with_static_data(|data| { - data.static_vars_cell.borrow_mut().call_value_egld_handle = handle; - }) - } - - fn get_call_value_egld_handle(&self) -> RawHandle { - self.with_static_data(|data| { - use_raw_handle(data.static_vars_cell.borrow().call_value_egld_handle) - }) - } - - fn set_call_value_multi_esdt_handle(&self, handle: RawHandle) { - self.with_static_data(|data| { - data.static_vars_cell - .borrow_mut() - .call_value_multi_esdt_handle = handle; - }) - } - - fn get_call_value_multi_esdt_handle(&self) -> RawHandle { - self.with_static_data(|data| { - use_raw_handle(data.static_vars_cell.borrow().call_value_multi_esdt_handle) - }) - } - fn is_scaling_factor_cached(&self, decimals: usize) -> bool { self.with_static_data(|data| data.static_vars_cell.borrow().scaling_factor_init[decimals]) } diff --git a/framework/scenario/src/debug_executor/tx_static_vars.rs b/framework/scenario/src/debug_executor/tx_static_vars.rs index bca543d8ba..3468d14da6 100644 --- a/framework/scenario/src/debug_executor/tx_static_vars.rs +++ b/framework/scenario/src/debug_executor/tx_static_vars.rs @@ -6,8 +6,6 @@ pub struct TxStaticVars { pub next_handle: RawHandle, pub num_arguments: i32, pub flags: StaticVarApiFlags, - pub call_value_egld_handle: RawHandle, - pub call_value_multi_esdt_handle: RawHandle, /// Vec of true/false, true if bit from handle = scaling_start + index is not empty pub scaling_factor_init: [bool; const_handles::SCALING_FACTOR_LENGTH], @@ -19,8 +17,6 @@ impl Default for TxStaticVars { external_view_target_address_handle: 0, next_handle: const_handles::NEW_HANDLE_START_FROM, num_arguments: -1, - call_value_egld_handle: const_handles::UNINITIALIZED_HANDLE, - call_value_multi_esdt_handle: const_handles::UNINITIALIZED_HANDLE, scaling_factor_init: [false; const_handles::SCALING_FACTOR_LENGTH], flags: StaticVarApiFlags::NONE, } diff --git a/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs b/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs index b282449c94..3c6b19996f 100644 --- a/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs +++ b/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs @@ -10,8 +10,6 @@ static mut EXTERNAL_VIEW_TARGET_ADDRESS_HANDLE: i32 = 0; static mut NEXT_HANDLE: i32 = const_handles::NEW_HANDLE_START_FROM; static mut NUM_ARGUMENTS: i32 = 0; static mut FLAGS: StaticVarApiFlags = StaticVarApiFlags::NONE; -static mut CALL_VALUE_EGLD_HANDLE: i32 = const_handles::UNINITIALIZED_HANDLE; -static mut CALL_VALUE_MULTI_ESDT_HANDLE: i32 = const_handles::UNINITIALIZED_HANDLE; static mut SCALING_FACTOR_INIT: [bool; const_handles::SCALING_FACTOR_LENGTH] = [false; const_handles::SCALING_FACTOR_LENGTH]; @@ -73,26 +71,6 @@ impl StaticVarApiImpl for VmApiImpl { unsafe { FLAGS } } - fn set_call_value_egld_handle(&self, handle: RawHandle) { - unsafe { - CALL_VALUE_EGLD_HANDLE = handle; - } - } - - fn get_call_value_egld_handle(&self) -> RawHandle { - unsafe { CALL_VALUE_EGLD_HANDLE } - } - - fn set_call_value_multi_esdt_handle(&self, handle: RawHandle) { - unsafe { - CALL_VALUE_MULTI_ESDT_HANDLE = handle; - } - } - - fn get_call_value_multi_esdt_handle(&self) -> RawHandle { - unsafe { CALL_VALUE_MULTI_ESDT_HANDLE } - } - fn is_scaling_factor_cached(&self, decimals: usize) -> bool { unsafe { SCALING_FACTOR_INIT[decimals] } } From e71d3e0080223c24089e6ec8e2652bec050ac7f6 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sat, 14 Dec 2024 07:52:46 +0200 Subject: [PATCH 093/133] BigInt cmp refactor --- .../src/types/managed/basic/big_int_cmp.rs | 11 +++++--- .../src/types/managed/basic/big_num_cmp.rs | 27 ++++++++++--------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/framework/base/src/types/managed/basic/big_int_cmp.rs b/framework/base/src/types/managed/basic/big_int_cmp.rs index 3cad2af277..9097909591 100644 --- a/framework/base/src/types/managed/basic/big_int_cmp.rs +++ b/framework/base/src/types/managed/basic/big_int_cmp.rs @@ -1,8 +1,11 @@ use core::cmp::Ordering; -use crate::api::{BigIntApiImpl, ManagedTypeApi}; +use crate::{ + api::{BigIntApiImpl, ManagedTypeApi}, + types::ManagedType, +}; -use super::{big_num_cmp::cmp_i64, BigInt}; +use super::{big_num_cmp::bi_cmp_i64, BigInt}; impl PartialEq for BigInt { #[inline] @@ -34,14 +37,14 @@ macro_rules! partial_eq_and_ord { impl PartialEq<$small_int_type> for BigInt { #[inline] fn eq(&self, other: &$small_int_type) -> bool { - cmp_i64(self, *other as i64).is_eq() + bi_cmp_i64::(self.get_handle(), *other as i64).is_eq() } } impl PartialOrd<$small_int_type> for BigInt { #[inline] fn partial_cmp(&self, other: &$small_int_type) -> Option { - Some(cmp_i64(self, *other as i64)) + Some(bi_cmp_i64::(self.get_handle(), *other as i64)) } } }; diff --git a/framework/base/src/types/managed/basic/big_num_cmp.rs b/framework/base/src/types/managed/basic/big_num_cmp.rs index 7793ea3e00..c5ce6da5a0 100644 --- a/framework/base/src/types/managed/basic/big_num_cmp.rs +++ b/framework/base/src/types/managed/basic/big_num_cmp.rs @@ -1,26 +1,29 @@ use core::cmp::Ordering; -use crate::{ - api::{const_handles, BigIntApiImpl, ManagedTypeApi}, - types::ManagedType, -}; +use crate::api::{const_handles, BigIntApiImpl, ManagedTypeApi}; use super::BigInt; -pub(crate) fn cmp_i64(bi: &B, other: i64) -> Ordering +pub(crate) fn bi_cmp_0(bi_handle: M::BigIntHandle) -> Ordering +where + M: ManagedTypeApi, +{ + match M::managed_type_impl().bi_sign(bi_handle) { + crate::api::Sign::Plus => Ordering::Greater, + crate::api::Sign::NoSign => Ordering::Equal, + crate::api::Sign::Minus => Ordering::Less, + } +} + +pub(crate) fn bi_cmp_i64(bi_handle: M::BigIntHandle, other: i64) -> Ordering where M: ManagedTypeApi, - B: ManagedType, { let api = M::managed_type_impl(); if other == 0 { - match api.bi_sign(bi.get_handle()) { - crate::api::Sign::Plus => Ordering::Greater, - crate::api::Sign::NoSign => Ordering::Equal, - crate::api::Sign::Minus => Ordering::Less, - } + bi_cmp_0::(bi_handle) } else { let big_int_temp_1 = BigInt::::make_temp(const_handles::BIG_INT_TEMPORARY_1, other); - api.bi_cmp(bi.get_handle(), big_int_temp_1) + api.bi_cmp(bi_handle, big_int_temp_1) } } From a74d5ae6beda5ea672d079ddf6f869e971bb8f47 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sat, 14 Dec 2024 07:53:25 +0200 Subject: [PATCH 094/133] BigInt clone refactor --- framework/base/src/types/managed/basic/big_int.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/framework/base/src/types/managed/basic/big_int.rs b/framework/base/src/types/managed/basic/big_int.rs index 464bc4150c..08adafea57 100644 --- a/framework/base/src/types/managed/basic/big_int.rs +++ b/framework/base/src/types/managed/basic/big_int.rs @@ -229,19 +229,19 @@ impl BigInt { result } } + + pub(crate) fn clone_to_handle(source_handle: M::BigIntHandle, dest_handle: M::BigIntHandle) { + let api = M::managed_type_impl(); + api.bi_set_int64(dest_handle.clone(), 0); + api.bi_add(dest_handle.clone(), dest_handle, source_handle); + } } impl Clone for BigInt { fn clone(&self) -> Self { - let api = M::managed_type_impl(); unsafe { let result = BigInt::new_uninit(); - api.bi_set_int64(result.get_handle(), 0); - api.bi_add( - result.get_handle(), - result.get_handle(), - self.handle.clone(), - ); + BigInt::::clone_to_handle(self.get_handle(), result.get_handle()); result } } From 39e64c20d6d4c22575b97274f5003b1cf140e429 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sat, 14 Dec 2024 08:52:56 +0200 Subject: [PATCH 095/133] call value - EGLD+ESDT support & backwards compatibility fix --- .../src/api/managed_types/const_handles.rs | 57 ++++-- .../api/managed_types/static_var_api_flags.rs | 29 +-- .../wrappers/call_value_wrapper.rs | 169 ++++++++++++------ .../src/types/managed/basic/big_num_cmp.rs | 11 +- framework/base/src/types/managed/basic/mod.rs | 2 +- 5 files changed, 187 insertions(+), 81 deletions(-) diff --git a/framework/base/src/api/managed_types/const_handles.rs b/framework/base/src/api/managed_types/const_handles.rs index 6d990f9c6e..ccf4e9a06c 100644 --- a/framework/base/src/api/managed_types/const_handles.rs +++ b/framework/base/src/api/managed_types/const_handles.rs @@ -7,26 +7,27 @@ pub const UNINITIALIZED_HANDLE: RawHandle = i32::MAX; /// WARNING! With the current VM this still needs to be initialized before use. pub const BIG_INT_CONST_ZERO: RawHandle = -10; - -pub const CALL_VALUE_EGLD: RawHandle = -11; -pub const CALL_VALUE_SINGLE_ESDT: RawHandle = -13; - -pub const BIG_INT_TEMPORARY_1: RawHandle = -14; -pub const BIG_INT_TEMPORARY_2: RawHandle = -15; -pub const BIG_FLOAT_TEMPORARY: RawHandle = -16; +pub const BIG_INT_TEMPORARY_1: RawHandle = -11; +pub const BIG_INT_TEMPORARY_2: RawHandle = -12; +pub const BIG_FLOAT_TEMPORARY: RawHandle = -15; /// WARNING! With the current VM this still needs to be initialized before use. pub const MBUF_CONST_EMPTY: RawHandle = -20; -pub const CALL_VALUE_MULTI_ESDT: RawHandle = -21; -pub const CALL_VALUE_SINGLE_ESDT_TOKEN_NAME: RawHandle = -22; -pub const CALLBACK_CLOSURE_ARGS_BUFFER: RawHandle = -23; pub const MBUF_TEMPORARY_1: RawHandle = -25; pub const MBUF_TEMPORARY_2: RawHandle = -26; -pub const MBUF_EGLD_000000: RawHandle = -27; pub const ADDRESS_CALLER: RawHandle = -30; pub const ADDRESS_SELF: RawHandle = -31; +pub const CALL_VALUE_EGLD: RawHandle = -35; +pub const CALL_VALUE_EGLD_MULTI: RawHandle = -36; +pub const CALL_VALUE_EGLD_FROM_ESDT: RawHandle = -37; +pub const CALL_VALUE_MULTI_ESDT: RawHandle = -38; +pub const CALL_VALUE_ALL: RawHandle = -39; +pub const MBUF_EGLD_000000: RawHandle = -40; + +pub const CALLBACK_CLOSURE_ARGS_BUFFER: RawHandle = -50; + pub const NEW_HANDLE_START_FROM: RawHandle = -200; // > -100 reserved for APIs // Vec of 64 entries of 1 bit @@ -40,3 +41,37 @@ pub const fn get_scaling_factor_handle(decimals: usize) -> i32 { let decimals_i32 = decimals as i32; SCALING_FACTOR_START - decimals_i32 } + +/// Payload of the singleton ManagedVec that contains the current single EGLD transfer, modelled as an ESDT payment. +pub const EGLD_PAYMENT_PAYLOAD: [u8; 16] = [ + 0xff, + 0xff, + 0xff, + (0x0100 + MBUF_EGLD_000000) as u8, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0xff, + 0xff, + 0xff, + (0x0100 + CALL_VALUE_EGLD) as u8, +]; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn egld_payment_payload_test() { + let mut bytes = [0u8; 4]; + bytes.copy_from_slice(&EGLD_PAYMENT_PAYLOAD[0..4]); + assert_eq!(i32::from_be_bytes(bytes), MBUF_EGLD_000000); + bytes.copy_from_slice(&EGLD_PAYMENT_PAYLOAD[12..16]); + assert_eq!(i32::from_be_bytes(bytes), CALL_VALUE_EGLD); + } +} diff --git a/framework/base/src/api/managed_types/static_var_api_flags.rs b/framework/base/src/api/managed_types/static_var_api_flags.rs index 1c9e153e69..2040d8acf3 100644 --- a/framework/base/src/api/managed_types/static_var_api_flags.rs +++ b/framework/base/src/api/managed_types/static_var_api_flags.rs @@ -3,11 +3,12 @@ use bitflags::bitflags; bitflags! { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct StaticVarApiFlags: u8 { - const NONE = 0b00000000; - const CALL_VALUE_EGLD_INITIALIZED = 0b00000001; - const CALL_VALUE_EGLD_MULTI_INITIALIZED = 0b00000010; - const CALL_VALUE_MULTI_ESDT_INITIALIZED = 0b00000100; - const CALL_VALUE_ALL_INITIALIZED = 0b00001000; + const NONE = 0b00000000; + const CALL_VALUE_EGLD_SINGLE_INITIALIZED = 0b00000001; + const CALL_VALUE_ESDT_UNCHECKED_INITIALIZED = 0b00000010; + const CALL_VALUE_EGLD_MULTI_INITIALIZED = 0b00000100; + const CALL_VALUE_EGLD_FROM_ESDT_INITIALIZED = 0b00001000; + const CALL_VALUE_ALL_INITIALIZED = 0b00010000; } } @@ -32,21 +33,27 @@ pub mod tests { assert!(current.check_and_set(StaticVarApiFlags::NONE)); assert_eq!(current, StaticVarApiFlags::NONE); - assert!(!current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED)); - assert_eq!(current, StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED); - assert!(current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED)); - assert_eq!(current, StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED); + assert!(!current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED)); + assert_eq!( + current, + StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED + ); + assert!(current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED)); + assert_eq!( + current, + StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED + ); assert!(!current.check_and_set(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED)); assert_eq!( current, - StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED + StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED | StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED ); assert!(current.check_and_set(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED)); assert_eq!( current, - StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED + StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED | StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED ); } diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 5fdfc795e7..7a1743b2e0 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -3,15 +3,14 @@ use core::marker::PhantomData; use crate::{ api::{ const_handles, use_raw_handle, CallValueApi, CallValueApiImpl, ErrorApi, ErrorApiImpl, - HandleConstraints, ManagedBufferApiImpl, ManagedTypeApi, RawHandle, StaticVarApiFlags, - StaticVarApiImpl, + ManagedBufferApiImpl, ManagedTypeApi, RawHandle, StaticVarApiFlags, StaticVarApiImpl, }, err_msg, types::{ - BigUint, ConstDecimals, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, - EgldOrMultiEsdtPayment, EsdtTokenPayment, ManagedDecimal, ManagedRef, ManagedType, - ManagedVec, ManagedVecItem, ManagedVecItemPayload, ManagedVecPayloadIterator, - ManagedVecRef, TokenIdentifier, EGLD_000000_TOKEN_IDENTIFIER, + big_num_cmp::bi_gt_zero, BigInt, BigUint, ConstDecimals, EgldOrEsdtTokenIdentifier, + EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, EsdtTokenPayment, ManagedDecimal, + ManagedRef, ManagedType, ManagedVec, ManagedVecItem, ManagedVecItemPayload, + ManagedVecPayloadIterator, ManagedVecRef, TokenIdentifier, EGLD_000000_TOKEN_IDENTIFIER, }, }; @@ -33,12 +32,47 @@ where } } + /// Cached transfers from the VM. + fn all_esdt_transfers_unchecked(&self) -> A::ManagedBufferHandle { + let all_transfers_unchecked_handle: A::ManagedBufferHandle = + use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT); + if !A::static_var_api_impl() + .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_ESDT_UNCHECKED_INITIALIZED) + { + A::call_value_api_impl() + .load_all_esdt_transfers(all_transfers_unchecked_handle.clone()); + } + all_transfers_unchecked_handle + } + + /// Cached egld transfer searched for in the ESDT transfers from the VM. + fn egld_from_multi_esdt(&self) -> A::BigIntHandle { + let egld_from_multi_esdt_handle: A::BigIntHandle = + use_raw_handle(const_handles::CALL_VALUE_EGLD_FROM_ESDT); + if !A::static_var_api_impl() + .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_FROM_ESDT_INITIALIZED) + { + let all_transfers_unchecked_handle = self.all_esdt_transfers_unchecked(); + let egld_handle_result = find_egld_000000_transfer::(all_transfers_unchecked_handle); + if let Some(found_egld_handle) = egld_handle_result { + BigInt::::clone_to_handle( + use_raw_handle(found_egld_handle), + egld_from_multi_esdt_handle.clone(), + ); + } else { + BigInt::::set_value(egld_from_multi_esdt_handle.clone(), 0); + } + } + egld_from_multi_esdt_handle + } + /// Retrieves the EGLD call value from the VM. - /// Will return 0 in case of an ESDT transfer (cannot have both EGLD and ESDT transfer simultaneously). + /// + /// Will return 0 in case of an ESDT transfer, even though EGLD and ESDT transfers are now posible. pub fn egld_value(&self) -> ManagedRef<'static, A, BigUint> { let call_value_handle: A::BigIntHandle = use_raw_handle(const_handles::CALL_VALUE_EGLD); if !A::static_var_api_impl() - .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED) + .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED) { A::call_value_api_impl().load_egld_value(call_value_handle.clone()); } @@ -52,23 +86,82 @@ where ) } + /// The quantity of EGLD transfered, either via simple EGLD transfer, or via ESDT multi-transfer. + pub fn egld_value_multi(&self) -> ManagedRef<'static, A, BigUint> { + let egld_value_multi_handle: A::BigIntHandle = + use_raw_handle(const_handles::CALL_VALUE_EGLD_MULTI); + if !A::static_var_api_impl() + .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_MULTI_INITIALIZED) + { + let egld_single = self.egld_value(); + if bi_gt_zero::(egld_single.get_handle()) { + BigInt::::clone_to_handle( + egld_single.get_handle(), + egld_value_multi_handle.clone(), + ); + } else { + let egld_from_multi_esdt_handle = self.egld_from_multi_esdt(); + BigInt::::clone_to_handle( + egld_from_multi_esdt_handle, + egld_value_multi_handle.clone(), + ); + } + } + unsafe { ManagedRef::wrap_handle(egld_value_multi_handle) } + } + /// Returns all ESDT transfers that accompany this SC call. /// Will return 0 results if nothing was transfered, or just EGLD. - /// Fully managed underlying types, very efficient. + /// + /// Will crash for EGLD + ESDT multi transfers. pub fn all_esdt_transfers(&self) -> ManagedRef<'static, A, ManagedVec>> { - let call_value_handle = load_all_transfers::(); - - let egld_payment = find_egld_000000_transfer::(call_value_handle.clone()); - if egld_payment.is_some() { - A::error_api_impl().signal_error(err_msg::ESDT_UNEXPECTED_EGLD.as_bytes()) + let multi_esdt_handle: A::ManagedBufferHandle = + use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT); + if !A::static_var_api_impl() + .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_ESDT_UNCHECKED_INITIALIZED) + { + let egld_value_multi_handle = self.egld_from_multi_esdt(); + if bi_gt_zero::(egld_value_multi_handle) { + A::error_api_impl().signal_error(err_msg::ESDT_UNEXPECTED_EGLD.as_bytes()) + } } - unsafe { ManagedRef::wrap_handle(call_value_handle) } + + unsafe { ManagedRef::wrap_handle(multi_esdt_handle) } } + /// Will return all transfers in the form of a list of EgldOrEsdtTokenPayment. + /// + /// Both EGLD and ESDT can be returned. + /// + /// In case of a single EGLD transfer, only one item will be returned, + /// the EGLD payment represented as an ESDT transfer (EGLD-000000). pub fn all_transfers( &self, ) -> ManagedRef<'static, A, ManagedVec>> { - let (_, all_transfers_handle) = load_all_call_data::(); + let all_transfers_handle: A::ManagedBufferHandle = + use_raw_handle(const_handles::CALL_VALUE_ALL); + if !A::static_var_api_impl() + .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED) + { + let egld_single = self.egld_value(); + if bi_gt_zero::(egld_single.get_handle()) { + A::managed_type_impl().mb_overwrite( + use_raw_handle(const_handles::MBUF_EGLD_000000), + EGLD_000000_TOKEN_IDENTIFIER.as_bytes(), + ); + let _ = A::managed_type_impl().mb_set_slice( + all_transfers_handle.clone(), + 0, + &const_handles::EGLD_PAYMENT_PAYLOAD[..], + ); + } else { + // clone all_esdt_transfers_unchecked -> all_transfers + let all_transfers_unchecked_handle = self.all_esdt_transfers_unchecked(); + let _ = A::managed_type_impl().mb_set_slice(all_transfers_handle.clone(), 0, &[]); + A::managed_type_impl() + .mb_append(all_transfers_handle.clone(), all_transfers_unchecked_handle); + } + } unsafe { ManagedRef::wrap_handle(all_transfers_handle) } } @@ -129,14 +222,16 @@ where /// /// In case no transfer of value happen, it will return a payment of 0 EGLD. pub fn egld_or_single_esdt(&self) -> EgldOrEsdtTokenPayment { - let esdt_transfers = self.all_esdt_transfers(); + let esdt_transfers_handle = self.all_esdt_transfers_unchecked(); + let esdt_transfers: ManagedRef<'static, A, ManagedVec>> = + unsafe { ManagedRef::wrap_handle(esdt_transfers_handle) }; match esdt_transfers.len() { 0 => EgldOrEsdtTokenPayment { token_identifier: EgldOrEsdtTokenIdentifier::egld(), token_nonce: 0, amount: self.egld_value().clone_value(), }, - 1 => esdt_transfers.get(0).clone().into(), + 1 => esdt_transfers.get(0).clone(), _ => A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_ESDT_TRANSFERS.as_bytes()), } } @@ -171,22 +266,6 @@ where } } -fn load_all_transfers() -> A::ManagedBufferHandle -where - A: CallValueApi + ErrorApi + ManagedTypeApi, -{ - // let mut all_transfers_handle: A::ManagedBufferHandle = - // use_raw_handle(A::static_var_api_impl().get_call_value_multi_esdt_handle()); - // if all_transfers_handle == const_handles::UNINITIALIZED_HANDLE { - // all_transfers_handle = use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT); - // A::static_var_api_impl() - // .set_call_value_multi_esdt_handle(all_transfers_handle.get_raw_handle()); - // A::call_value_api_impl().load_all_esdt_transfers(all_transfers_handle.clone()); - // } - // all_transfers_handle - todo!() -} - fn find_egld_000000_transfer(transfers_vec_handle: A::ManagedBufferHandle) -> Option where A: CallValueApi + ErrorApi + ManagedTypeApi, @@ -217,25 +296,3 @@ where egld_payload.map(|payload| RawHandle::read_from_payload(payload.slice_unchecked(12))) } } - -fn load_all_call_data() -> (A::BigIntHandle, A::ManagedBufferHandle) -where - A: CallValueApi + ErrorApi + ManagedTypeApi, -{ - // let all_transfers_handle = load_all_transfers::(); - // let mut egld_amount_handle: A::BigIntHandle = - // use_raw_handle(A::static_var_api_impl().get_call_value_egld_handle()); - // if egld_amount_handle == const_handles::UNINITIALIZED_HANDLE { - // let egld_payment = find_egld_000000_transfer::(all_transfers_handle.clone()); - // if let Some(egld_amount_raw_handle) = egld_payment { - // egld_amount_handle = use_raw_handle(egld_amount_raw_handle); - // } else { - // egld_amount_handle = use_raw_handle(const_handles::CALL_VALUE_EGLD); - // A::call_value_api_impl().load_egld_value(egld_amount_handle.clone()); - // } - // A::static_var_api_impl().set_call_value_egld_handle(egld_amount_handle.get_raw_handle()); - // } - - // (egld_amount_handle, all_transfers_handle) - todo!() -} diff --git a/framework/base/src/types/managed/basic/big_num_cmp.rs b/framework/base/src/types/managed/basic/big_num_cmp.rs index c5ce6da5a0..dcb3bc6c49 100644 --- a/framework/base/src/types/managed/basic/big_num_cmp.rs +++ b/framework/base/src/types/managed/basic/big_num_cmp.rs @@ -4,7 +4,7 @@ use crate::api::{const_handles, BigIntApiImpl, ManagedTypeApi}; use super::BigInt; -pub(crate) fn bi_cmp_0(bi_handle: M::BigIntHandle) -> Ordering +pub(crate) fn bi_cmp_zero(bi_handle: M::BigIntHandle) -> Ordering where M: ManagedTypeApi, { @@ -15,13 +15,20 @@ where } } +pub(crate) fn bi_gt_zero(bi_handle: M::BigIntHandle) -> bool +where + M: ManagedTypeApi, +{ + bi_cmp_zero::(bi_handle) == Ordering::Greater +} + pub(crate) fn bi_cmp_i64(bi_handle: M::BigIntHandle, other: i64) -> Ordering where M: ManagedTypeApi, { let api = M::managed_type_impl(); if other == 0 { - bi_cmp_0::(bi_handle) + bi_cmp_zero::(bi_handle) } else { let big_int_temp_1 = BigInt::::make_temp(const_handles::BIG_INT_TEMPORARY_1, other); api.bi_cmp(bi_handle, big_int_temp_1) diff --git a/framework/base/src/types/managed/basic/mod.rs b/framework/base/src/types/managed/basic/mod.rs index ef10f15b5e..253adc0fb8 100644 --- a/framework/base/src/types/managed/basic/mod.rs +++ b/framework/base/src/types/managed/basic/mod.rs @@ -5,7 +5,7 @@ mod big_int; mod big_int_cmp; mod big_int_operators; mod big_int_sign; -mod big_num_cmp; +pub(crate) mod big_num_cmp; pub(crate) mod cast_to_i64; mod elliptic_curve; mod managed_buffer; From 45803411df28dd38d9eec9dab25e10c6a35e307f Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sun, 15 Dec 2024 04:37:44 +0200 Subject: [PATCH 096/133] bugfix --- .../base/src/contract_base/wrappers/call_value_wrapper.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 7a1743b2e0..3304bfdcf2 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -115,8 +115,7 @@ where /// /// Will crash for EGLD + ESDT multi transfers. pub fn all_esdt_transfers(&self) -> ManagedRef<'static, A, ManagedVec>> { - let multi_esdt_handle: A::ManagedBufferHandle = - use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT); + let multi_esdt_handle: A::ManagedBufferHandle = self.all_esdt_transfers_unchecked(); if !A::static_var_api_impl() .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_ESDT_UNCHECKED_INITIALIZED) { From c73b9cc37e33f0ec85be02966a2ca331964d933a Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Fri, 20 Dec 2024 09:02:05 +0100 Subject: [PATCH 097/133] replaced bech32::decode() with Address::zero() to avoid panics --- .../forwarder-interactor/src/interact.rs | 96 +++++++++---------- 1 file changed, 43 insertions(+), 53 deletions(-) diff --git a/contracts/feature-tests/composability/forwarder-interactor/src/interact.rs b/contracts/feature-tests/composability/forwarder-interactor/src/interact.rs index bce4d4798c..83921f981a 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/src/interact.rs +++ b/contracts/feature-tests/composability/forwarder-interactor/src/interact.rs @@ -118,7 +118,6 @@ pub async fn forwarder_cli() { "get_nft_balance" => interact.get_nft_balance().await, "buy_nft" => interact.buy_nft().await, "nft_issue" => interact.nft_issue().await, - // "nft_create" => interact.nft_create().await, "nft_create_compact" => interact.nft_create_compact().await, "nft_add_uris" => interact.nft_add_uris().await, "nft_update_attributes" => interact.nft_update_attributes().await, @@ -130,15 +129,6 @@ pub async fn forwarder_cli() { "create_and_send" => interact.create_and_send().await, "setLocalRoles" => interact.set_local_roles().await, "unsetLocalRoles" => interact.unset_local_roles().await, - // "issue_dynamic_token" => interact.issue_dynamic_token().await, - // "change_to_dynamic" => interact.change_to_dynamic().await, - // "update_token" => interact.update_token().await, - // "modify_royalties" => interact.modify_royalties().await, - // "set_new_uris" => interact.set_new_uris().await, - // "modify_creator" => interact.modify_creator().await, - // "metadata_recreate" => interact.metadata_recreate().await, - // "metadata_update" => interact.metadata_update().await, - // "lastIssuedToken" => interact.last_issued_token().await, "lastErrorMessage" => interact.last_error_message().await, _ => panic!("unknown command: {}", &cmd), } @@ -242,7 +232,7 @@ impl ContractInteract { } pub async fn send_egld(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let amount = BigUint::::from(0u128); let response = self @@ -265,7 +255,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let args = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); let response = self @@ -293,7 +283,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let args = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); let response = self @@ -321,7 +311,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let response = self .interactor @@ -346,7 +336,7 @@ impl ContractInteract { pub async fn forward_sync_accept_funds_rh_egld(&mut self) { let egld_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let response = self .interactor @@ -369,7 +359,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let response = self .interactor @@ -396,7 +386,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let response = self .interactor @@ -423,7 +413,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let percentage_fees = BigUint::::from(0u128); let response = self @@ -451,7 +441,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let response = self .interactor @@ -474,7 +464,7 @@ impl ContractInteract { } pub async fn forward_sync_retrieve_funds(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token = EgldOrEsdtTokenIdentifier::esdt(&b""[..]); let token_nonce = 0u64; let amount = BigUint::::from(0u128); @@ -499,7 +489,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let token = TokenIdentifier::from_esdt_bytes(&b""[..]); let amount = BigUint::::from(0u128); @@ -549,7 +539,7 @@ impl ContractInteract { } pub async fn forward_sync_accept_funds_multi_transfer(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_payments = MultiValueVec::from(vec![MultiValue3::< TokenIdentifier, u64, @@ -576,7 +566,7 @@ impl ContractInteract { } pub async fn echo_args_async(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let args = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]); let response = self @@ -599,7 +589,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let response = self .interactor @@ -626,7 +616,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let response = self .interactor @@ -653,7 +643,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let percentage_fees = BigUint::::from(0u128); let response = self @@ -677,7 +667,7 @@ impl ContractInteract { } pub async fn forward_async_retrieve_funds(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token = EgldOrEsdtTokenIdentifier::esdt(&b""[..]); let token_nonce = 0u64; let amount = BigUint::::from(0u128); @@ -698,7 +688,7 @@ impl ContractInteract { } pub async fn send_funds_twice(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_identifier = EgldOrEsdtTokenIdentifier::esdt(&b""[..]); let amount = BigUint::::from(0u128); @@ -718,7 +708,7 @@ impl ContractInteract { } pub async fn send_async_accept_multi_transfer(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_payments = MultiValueVec::from(vec![MultiValue3::< TokenIdentifier, u64, @@ -795,7 +785,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let response = self .interactor @@ -822,7 +812,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let percentage_fees = BigUint::::from(0u128); let response = self @@ -850,7 +840,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let response = self .interactor @@ -877,7 +867,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let response = self .interactor @@ -900,7 +890,7 @@ impl ContractInteract { } pub async fn transf_exec_multi_accept_funds(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_payments = MultiValueVec::from(vec![MultiValue3::< TokenIdentifier, u64, @@ -927,7 +917,7 @@ impl ContractInteract { } pub async fn forward_transf_exec_reject_funds_multi_transfer(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_payments = MultiValueVec::from(vec![MultiValue3::< TokenIdentifier, u64, @@ -954,7 +944,7 @@ impl ContractInteract { } pub async fn transf_exec_multi_reject_funds(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_payments = MultiValueVec::from(vec![MultiValue3::< TokenIdentifier, u64, @@ -981,8 +971,8 @@ impl ContractInteract { } pub async fn change_owner(&mut self) { - let child_sc_address = bech32::decode(""); - let new_owner = bech32::decode(""); + let child_sc_address = Address::zero(); + let new_owner = Address::zero(); let response = self .interactor @@ -1037,7 +1027,7 @@ impl ContractInteract { } pub async fn deploy_vault_from_source(&mut self) { - let source_address = bech32::decode(""); + let source_address = Address::zero(); let opt_arg = OptionalValue::Some(ManagedBuffer::new_from_bytes(&b""[..])); let response = self @@ -1056,7 +1046,7 @@ impl ContractInteract { } pub async fn upgrade_vault(&mut self) { - let child_sc_address = bech32::decode(""); + let child_sc_address = Address::zero(); let new_code = ManagedBuffer::new_from_bytes(&b""[..]); let opt_arg = OptionalValue::Some(ManagedBuffer::new_from_bytes(&b""[..])); @@ -1076,8 +1066,8 @@ impl ContractInteract { } pub async fn upgrade_vault_from_source(&mut self) { - let child_sc_address = bech32::decode(""); - let source_address = bech32::decode(""); + let child_sc_address = Address::zero(); + let source_address = Address::zero(); let opt_arg = OptionalValue::Some(ManagedBuffer::new_from_bytes(&b""[..])); let response = self @@ -1128,7 +1118,7 @@ impl ContractInteract { } pub async fn send_esdt(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); let amount = BigUint::::from(0u128); @@ -1152,7 +1142,7 @@ impl ContractInteract { let token_nonce = 0u64; let token_amount = BigUint::::from(0u128); - let to = bech32::decode(""); + let to = Address::zero(); let percentage_fees = BigUint::::from(0u128); let response = self @@ -1176,7 +1166,7 @@ impl ContractInteract { } pub async fn send_esdt_twice(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); let amount_first_time = BigUint::::from(0u128); let amount_second_time = BigUint::::from(0u128); @@ -1197,7 +1187,7 @@ impl ContractInteract { } pub async fn send_esdt_direct_multi_transfer(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_payments = MultiValueVec::from(vec![MultiValue3::< TokenIdentifier, u64, @@ -1301,7 +1291,7 @@ impl ContractInteract { } pub async fn get_esdt_token_data(&mut self) { - let address = bech32::decode(""); + let address = Address::zero(); let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); let nonce = 0u64; @@ -1319,7 +1309,7 @@ impl ContractInteract { } pub async fn is_esdt_frozen(&mut self) { - let address = bech32::decode(""); + let address = Address::zero(); let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]); let nonce = 0u64; @@ -1655,7 +1645,7 @@ impl ContractInteract { } pub async fn transfer_nft_via_async_call(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); let nonce = 0u64; let amount = BigUint::::from(0u128); @@ -1676,7 +1666,7 @@ impl ContractInteract { } pub async fn transfer_nft_and_execute(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); let nonce = 0u64; let amount = BigUint::::from(0u128); @@ -1699,7 +1689,7 @@ impl ContractInteract { } pub async fn create_and_send(&mut self) { - let to = bech32::decode(""); + let to = Address::zero(); let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); let amount = BigUint::::from(0u128); let name = ManagedBuffer::new_from_bytes(&b""[..]); @@ -1733,7 +1723,7 @@ impl ContractInteract { } pub async fn set_local_roles(&mut self) { - let address = bech32::decode(""); + let address = Address::zero(); let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); let roles = MultiValueVec::::new(); @@ -1753,7 +1743,7 @@ impl ContractInteract { } pub async fn unset_local_roles(&mut self) { - let address = bech32::decode(""); + let address = Address::zero(); let token_identifier = TokenIdentifier::from_esdt_bytes(&b""[..]); let roles = MultiValueVec::::new(); From 24ddb51e80e30c3eabf6ffe67a32275d71e00bc2 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Fri, 20 Dec 2024 10:41:19 +0100 Subject: [PATCH 098/133] force home package version for nightly builds ci/cd fix --- framework/meta/Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/framework/meta/Cargo.toml b/framework/meta/Cargo.toml index 3d92426f81..1b07fca11b 100644 --- a/framework/meta/Cargo.toml +++ b/framework/meta/Cargo.toml @@ -40,7 +40,8 @@ copy_dir = "0.1.2" pathdiff = "0.2.1" common-path = "1.0.0" bip39 = "2.0.0" -home = "0.5.2" +# TODO: 0.5.11 doesn't support rustc 1.80, needs >= 1.81 (issue on ci/cd for nightly builds) +home = "=0.5.5" [dependencies.multiversx-sc-meta-lib] version = "=0.54.5" From 3d20aaca4827e2b6e479c1110d7c102ea37e38b0 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 20 Dec 2024 11:41:25 +0200 Subject: [PATCH 099/133] undo scenario self test rename --- .../scenario/tests/scenarios_self_go_test.rs | 181 ------------------ ...self_rs_test.rs => scenarios_self_test.rs} | 1 + 2 files changed, 1 insertion(+), 181 deletions(-) delete mode 100644 framework/scenario/tests/scenarios_self_go_test.rs rename framework/scenario/tests/{scenarios_self_rs_test.rs => scenarios_self_test.rs} (98%) diff --git a/framework/scenario/tests/scenarios_self_go_test.rs b/framework/scenario/tests/scenarios_self_go_test.rs deleted file mode 100644 index 87bb7ae7c5..0000000000 --- a/framework/scenario/tests/scenarios_self_go_test.rs +++ /dev/null @@ -1,181 +0,0 @@ -use multiversx_sc_scenario::*; - -// These tests don't really test any contract, but the testing framework itself. - -fn world() -> ScenarioWorld { - ScenarioWorld::vm_go() -} - -/// Checks that externalSteps work fine. -#[test] -fn external_steps_go() { - world().run("tests/scenarios-self/external_steps/external_steps.scen.json"); -} - -#[test] -#[should_panic] -fn set_account_addr_len_err1_go() { - world().run("tests/scenarios-self/set-check/set-account-addr-len.err1.json"); -} - -#[test] -#[should_panic] -fn set_account_addr_len_err2_go() { - world().run("tests/scenarios-self/set-check/set-account-addr-len.err2.json"); -} - -#[test] -#[should_panic] -fn set_account_sc_addr_err1_go() { - world().run("tests/scenarios-self/set-check/set-account-sc-addr.err1.json"); -} - -#[test] -#[should_panic] -fn set_account_sc_addr_err2_go() { - world().run("tests/scenarios-self/set-check/set-account-sc-addr.err2.json"); -} - -#[test] -#[should_panic] -fn set_account_sc_addr_err3_go() { - world().run("tests/scenarios-self/set-check/set-account-sc-addr.err3.json"); -} - -#[test] -#[should_panic] -fn set_check_balance_err_go() { - world().run("tests/scenarios-self/set-check/set-check-balance.err.json"); -} - -#[test] -fn set_check_balance_go() { - world().run("tests/scenarios-self/set-check/set-check-balance.scen.json"); -} - -#[test] -#[should_panic] -fn set_check_code_err_go() { - world().run("tests/scenarios-self/set-check/set-check-code.err.json"); -} - -#[test] -fn set_check_code() { - world().run("tests/scenarios-self/set-check/set-check-code.scen.json"); -} - -#[test] -#[should_panic] -fn set_check_codemetadata_err_go() { - world().run("tests/scenarios-self/set-check/set-check-codemetadata.err.json"); -} - -#[test] -fn set_check_codemetadata() { - world().run("tests/scenarios-self/set-check/set-check-codemetadata.scen.json"); -} - -#[test] -#[should_panic] -fn set_check_esdt_err_go() { - world().run("tests/scenarios-self/set-check/set-check-esdt.err1.json"); -} - -#[test] -fn set_check_esdt_go() { - world().run("tests/scenarios-self/set-check/set-check-esdt.scen.json"); -} - -#[test] -#[should_panic] -fn set_check_nonce_err_go() { - world().run("tests/scenarios-self/set-check/set-check-nonce.err.json"); -} - -#[test] -fn set_check_nonce_go() { - world().run("tests/scenarios-self/set-check/set-check-nonce.scen.json"); -} - -#[test] -#[should_panic] -fn set_check_storage_err1_go() { - world().run("tests/scenarios-self/set-check/set-check-storage.err1.json"); -} - -#[test] -#[should_panic] -fn set_check_storage_err2_go() { - world().run("tests/scenarios-self/set-check/set-check-storage.err2.json"); -} - -#[test] -#[should_panic] -fn set_check_storage_err3_go() { - world().run("tests/scenarios-self/set-check/set-check-storage.err3.json"); -} - -#[test] -#[should_panic] -fn set_check_storage_err4_go() { - world().run("tests/scenarios-self/set-check/set-check-storage.err4.json"); -} - -#[test] -#[should_panic] -fn set_check_storage_err5_go() { - world().run("tests/scenarios-self/set-check/set-check-storage.err5.json"); -} - -#[test] -fn set_check_storage_go() { - world().run("tests/scenarios-self/set-check/set-check-storage.scen.json"); -} - -#[test] -#[should_panic] -fn set_check_username_err_go() { - world().run("tests/scenarios-self/set-check/set-check-username.err.json"); -} - -#[test] -fn set_check_username_go() { - world().run("tests/scenarios-self/set-check/set-check-username.scen.json"); -} - -#[test] -fn builtin_func_esdt_transfer() { - world().run("tests/scenarios-self/builtin-func-esdt-transfer.scen.json"); -} - -#[test] -#[should_panic] -fn esdt_non_zero_balance_check_err_go() { - world().run("tests/scenarios-self/esdt-non-zero-balance-check-err.scen.json"); -} - -#[test] -#[should_panic] -fn esdt_zero_balance_check_err_go() { - world().run("tests/scenarios-self/esdt-zero-balance-check-err.scen.json"); -} - -#[test] -fn multi_transfer_esdt_go() { - world().run("tests/scenarios-self/multi-transfer-esdt.scen.json"); -} - -#[test] -fn transfer_egld_go() { - world().run("tests/scenarios-self/transfer-egld.scen.json"); -} - -#[test] -fn transfer_esdt_go() { - world().run("tests/scenarios-self/transfer-esdt.scen.json"); -} - -#[test] -fn validator_reward_go() { - world().run("tests/scenarios-self/validatorReward.scen.json"); -} diff --git a/framework/scenario/tests/scenarios_self_rs_test.rs b/framework/scenario/tests/scenarios_self_test.rs similarity index 98% rename from framework/scenario/tests/scenarios_self_rs_test.rs rename to framework/scenario/tests/scenarios_self_test.rs index b6bf9c1883..bcdbd17993 100644 --- a/framework/scenario/tests/scenarios_self_rs_test.rs +++ b/framework/scenario/tests/scenarios_self_test.rs @@ -161,6 +161,7 @@ fn esdt_zero_balance_check_err_rs() { } #[test] +#[ignore = "TODO: not yet implemented in Rust VM"] fn multi_transfer_esdt_rs() { world().run("tests/scenarios-self/multi-transfer-esdt.scen.json"); } From e8d9f647f1d0ca2293d00f35a01956aa3bf00da7 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sun, 22 Dec 2024 13:10:48 +0200 Subject: [PATCH 100/133] scenario self test transfer cleanup --- .../multi-transfer-egld.scen.json | 100 ++++++++++++++++++ .../multi-transfer-esdt.scen.json | 9 +- .../scenario/tests/scenarios_self_test.rs | 5 + 3 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 framework/scenario/tests/scenarios-self/multi-transfer-egld.scen.json diff --git a/framework/scenario/tests/scenarios-self/multi-transfer-egld.scen.json b/framework/scenario/tests/scenarios-self/multi-transfer-egld.scen.json new file mode 100644 index 0000000000..32b5ee3aa1 --- /dev/null +++ b/framework/scenario/tests/scenarios-self/multi-transfer-egld.scen.json @@ -0,0 +1,100 @@ +{ + "comment": "ESDT multi-transfer with EGLD, no SC", + "steps": [ + { + "step": "setState", + "accounts": { + "address:A": { + "nonce": "0", + "balance": "1000000000", + "esdt": { + "str:TOK-123456": "150", + "str:OTHERTOK-123456": "500", + "str:NFT-123456": { + "instances": [ + { + "nonce": "5", + "balance": "20" + } + ] + } + } + }, + "address:B": { + "nonce": "0", + "balance": "0" + } + } + }, + { + "step": "transfer", + "id": "multi-transfer", + "tx": { + "from": "address:A", + "to": "address:B", + "esdtValue": [ + { + "tokenIdentifier": "str:TOK-123456", + "value": "100" + }, + { + "tokenIdentifier": "str:OTHERTOK-123456", + "value": "400" + }, + { + "tokenIdentifier": "str:EGLD-000000", + "value": "500" + }, + { + "tokenIdentifier": "str:NFT-123456", + "nonce": "5", + "value": "10" + } + ], + "gasLimit": "0x100000000" + } + }, + { + "step": "checkState", + "comment": "check after tx 1", + "accounts": { + "address:A": { + "nonce": "1", + "balance": "999999500", + "esdt": { + "str:TOK-123456": "50", + "str:OTHERTOK-123456": "100", + "str:NFT-123456": { + "instances": [ + { + "nonce": "5", + "balance": "10" + } + ] + } + }, + "storage": {}, + "code": "" + }, + "address:B": { + "nonce": "0", + "balance": "500", + "esdt": { + "str:TOK-123456": "100", + "str:OTHERTOK-123456": "400", + "str:NFT-123456": { + "instances": [ + { + "nonce": "5", + "balance": "10" + } + ] + } + }, + "storage": {}, + "code": "" + } + } + } + ] +} \ No newline at end of file diff --git a/framework/scenario/tests/scenarios-self/multi-transfer-esdt.scen.json b/framework/scenario/tests/scenarios-self/multi-transfer-esdt.scen.json index 9aad78288d..09ebf399dd 100644 --- a/framework/scenario/tests/scenarios-self/multi-transfer-esdt.scen.json +++ b/framework/scenario/tests/scenarios-self/multi-transfer-esdt.scen.json @@ -41,10 +41,6 @@ "tokenIdentifier": "str:OTHERTOK-123456", "value": "400" }, - { - "tokenIdentifier": "str:EGLD-000000", - "value": "500" - }, { "tokenIdentifier": "str:NFT-123456", "nonce": "5", @@ -60,7 +56,7 @@ "accounts": { "address:A": { "nonce": "1", - "balance": "999999500", + "balance": "1000000000", "esdt": { "str:TOK-123456": "50", "str:OTHERTOK-123456": "100", @@ -78,7 +74,6 @@ }, "address:B": { "nonce": "0", - "balance": "500", "esdt": { "str:TOK-123456": "100", "str:OTHERTOK-123456": "400", @@ -97,4 +92,4 @@ } } ] -} \ No newline at end of file +} diff --git a/framework/scenario/tests/scenarios_self_test.rs b/framework/scenario/tests/scenarios_self_test.rs index bcdbd17993..94f63a0539 100644 --- a/framework/scenario/tests/scenarios_self_test.rs +++ b/framework/scenario/tests/scenarios_self_test.rs @@ -162,6 +162,11 @@ fn esdt_zero_balance_check_err_rs() { #[test] #[ignore = "TODO: not yet implemented in Rust VM"] +fn multi_transfer_egld_rs() { + world().run("tests/scenarios-self/multi-transfer-esdt.scen.json"); +} + +#[test] fn multi_transfer_esdt_rs() { world().run("tests/scenarios-self/multi-transfer-esdt.scen.json"); } From d96df7d1f80a1c5b7e65dcfa18a9983ffaf63eb8 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 23 Dec 2024 07:54:36 +0200 Subject: [PATCH 101/133] separate multi egld tests --- ...warder_call_async_multi_transfer.scen.json | 13 +- ...r_call_async_multi_transfer_egld.scen.json | 206 ++++++++++++++++++ .../call-value-check-multi-egld.scen.json | 128 +++++++++++ .../scenarios/call-value-check.scen.json | 8 +- .../scenarios/payable_multi_array.scen.json | 11 +- .../payable_multi_array_egld.scen.json | 146 +++++++++++++ .../scenarios/payable_multiple.scen.json | 10 +- .../scenarios/payable_multiple_egld.scen.json | 78 +++++++ 8 files changed, 570 insertions(+), 30 deletions(-) create mode 100644 contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer_egld.scen.json create mode 100644 contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json create mode 100644 contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json create mode 100644 contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json index 7dc86ee64f..81b18ee338 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json @@ -10,7 +10,7 @@ }, "sc:forwarder": { "nonce": "0", - "balance": "4000", + "balance": "0", "esdt": { "str:FWD-TOKEN": "1000", "str:NFT-123456": { @@ -89,7 +89,7 @@ }, "sc:forwarder": { "nonce": "0", - "balance": "4000", + "balance": "0", "esdt": { "str:FWD-TOKEN": "700", "str:NFT-123456": { @@ -130,9 +130,6 @@ "str:NFT-123456", "1", "1", - "str:EGLD-000000", - "0", - "100", "str:SFT-456789", "3", "6" @@ -159,7 +156,7 @@ }, "sc:vault": { "nonce": "0", - "balance": "100", + "balance": "0", "esdt": { "str:FWD-TOKEN": "800", "str:NFT-123456": { @@ -186,7 +183,7 @@ }, "sc:forwarder": { "nonce": "0", - "balance": "3900", + "balance": "0", "esdt": { "str:FWD-TOKEN": "200", "str:SFT-456789": { @@ -203,4 +200,4 @@ } } ] -} \ No newline at end of file +} diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer_egld.scen.json new file mode 100644 index 0000000000..7dc86ee64f --- /dev/null +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer_egld.scen.json @@ -0,0 +1,206 @@ +{ + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "address:a_user": { + "nonce": "0", + "balance": "0" + }, + "sc:forwarder": { + "nonce": "0", + "balance": "4000", + "esdt": { + "str:FWD-TOKEN": "1000", + "str:NFT-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1" + } + ] + }, + "str:SFT-456789": { + "instances": [ + { + "nonce": "3", + "balance": "10" + } + ] + } + }, + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" + }, + "sc:vault": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../vault/output/vault.mxsc.json" + } + } + }, + { + "step": "scCall", + "id": "1", + "comment": "send fungible twice", + "tx": { + "from": "address:a_user", + "to": "sc:forwarder", + "function": "send_async_accept_multi_transfer", + "arguments": [ + "sc:vault", + "str:FWD-TOKEN", + "0", + "100", + "str:FWD-TOKEN", + "0", + "200" + ], + "gasLimit": "80,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "address:a_user": { + "nonce": "*", + "balance": "0", + "storage": {}, + "code": "" + }, + "sc:vault": { + "nonce": "0", + "balance": "0", + "esdt": { + "str:FWD-TOKEN": "300" + }, + "storage": { + "str:call_counts|nested:str:accept_funds": "1" + }, + "code": "mxsc:../vault/output/vault.mxsc.json" + }, + "sc:forwarder": { + "nonce": "0", + "balance": "4000", + "esdt": { + "str:FWD-TOKEN": "700", + "str:NFT-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1" + } + ] + }, + "str:SFT-456789": { + "instances": [ + { + "nonce": "3", + "balance": "10" + } + ] + } + }, + "storage": {}, + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" + } + } + }, + { + "step": "scCall", + "id": "2", + "comment": "send all types", + "tx": { + "from": "address:a_user", + "to": "sc:forwarder", + "function": "send_async_accept_multi_transfer", + "arguments": [ + "sc:vault", + "str:FWD-TOKEN", + "0", + "500", + "str:NFT-123456", + "1", + "1", + "str:EGLD-000000", + "0", + "100", + "str:SFT-456789", + "3", + "6" + ], + "gasLimit": "80,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "address:a_user": { + "nonce": "*", + "balance": "0", + "storage": {}, + "code": "" + }, + "sc:vault": { + "nonce": "0", + "balance": "100", + "esdt": { + "str:FWD-TOKEN": "800", + "str:NFT-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1" + } + ] + }, + "str:SFT-456789": { + "instances": [ + { + "nonce": "3", + "balance": "6" + } + ] + } + }, + "storage": { + "str:call_counts|nested:str:accept_funds": "2" + }, + "code": "mxsc:../vault/output/vault.mxsc.json" + }, + "sc:forwarder": { + "nonce": "0", + "balance": "3900", + "esdt": { + "str:FWD-TOKEN": "200", + "str:SFT-456789": { + "instances": [ + { + "nonce": "3", + "balance": "4" + } + ] + } + }, + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" + } + } + } + ] +} \ No newline at end of file diff --git a/contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json b/contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json new file mode 100644 index 0000000000..8490c055fe --- /dev/null +++ b/contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json @@ -0,0 +1,128 @@ +{ + "steps": [ + { + "step": "setState", + "accounts": { + "sc:payable-features": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/payable-features.mxsc.json" + }, + "address:an-account": { + "nonce": "0", + "balance": "10000", + "esdt": { + "str:TOK-123456": "1000", + "str:OTHERTOK-123456": "500", + "str:SFT-123": { + "instances": [ + { + "nonce": "5", + "balance": "20" + } + ] + } + } + } + } + }, + { + "step": "scCall", + "id": "call-value-egld", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "egldValue": "100", + "function": "echo_call_value", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "100", + "" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "call-value-single-esdt", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:TOK-123456", + "value": "100" + } + ], + "function": "echo_call_value", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0", + [ + "nested:str:TOK-123456|u64:0|biguint:100" + ] + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "call-value-multi-esdt", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:EGLD-000000", + "value": "15" + }, + { + "tokenIdentifier": "str:TOK-123456", + "value": "100" + }, + { + "tokenIdentifier": "str:OTHERTOK-123456", + "value": "400" + }, + { + "tokenIdentifier": "str:SFT-123", + "nonce": "5", + "value": "10" + } + ], + "function": "echo_call_value", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "15", + [ + "nested:str:TOK-123456|u64:0|biguint:100", + "nested:str:OTHERTOK-123456|u64:0|biguint:400", + "nested:str:SFT-123|u64:5|biguint:10" + ] + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} \ No newline at end of file diff --git a/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json b/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json index 8490c055fe..23da3773d6 100644 --- a/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json @@ -86,10 +86,6 @@ "from": "address:an-account", "to": "sc:payable-features", "esdtValue": [ - { - "tokenIdentifier": "str:EGLD-000000", - "value": "15" - }, { "tokenIdentifier": "str:TOK-123456", "value": "100" @@ -111,7 +107,7 @@ }, "expect": { "out": [ - "15", + "0", [ "nested:str:TOK-123456|u64:0|biguint:100", "nested:str:OTHERTOK-123456|u64:0|biguint:400", @@ -125,4 +121,4 @@ } } ] -} \ No newline at end of file +} diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json index 16fa1cea20..b05028dfae 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json @@ -52,11 +52,6 @@ "tokenIdentifier": "str:SFT-123", "nonce": "5", "value": "10" - }, - { - "tokenIdentifier": "str:EGLD-000000", - "nonce": "0", - "value": "103" } ], "function": "payment_array_3", @@ -116,7 +111,7 @@ "value": "100" }, { - "tokenIdentifier": "str:EGLD-000000", + "tokenIdentifier": "str:TOK-000002", "value": "400" }, { @@ -133,7 +128,7 @@ "expect": { "out": [ "nested:str:TOK-000001|u64:0|biguint:100", - "nested:str:EGLD-000000|u64:0|biguint:400", + "nested:str:TOK-000002|u64:0|biguint:400", "nested:str:SFT-123|u64:5|biguint:10" ], "status": "", @@ -143,4 +138,4 @@ } } ] -} \ No newline at end of file +} diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json new file mode 100644 index 0000000000..16fa1cea20 --- /dev/null +++ b/contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json @@ -0,0 +1,146 @@ +{ + "name": "payable", + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:payable-features": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/payable-features.mxsc.json" + }, + "address:an-account": { + "nonce": "0", + "balance": "10000", + "esdt": { + "str:TOK-000001": "1000", + "str:TOK-000002": "500", + "str:TOK-000003": "500", + "str:SFT-123": { + "instances": [ + { + "nonce": "5", + "balance": "20" + } + ] + } + } + } + } + }, + { + "step": "scCall", + "id": "payment-array-too-many", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:TOK-000001", + "value": "100" + }, + { + "tokenIdentifier": "str:TOK-000002", + "value": "400" + }, + { + "tokenIdentifier": "str:TOK-000003", + "value": "400" + }, + { + "tokenIdentifier": "str:SFT-123", + "nonce": "5", + "value": "10" + }, + { + "tokenIdentifier": "str:EGLD-000000", + "nonce": "0", + "value": "103" + } + ], + "function": "payment_array_3", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:incorrect number of ESDT transfers", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "payment-array-too-few", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:TOK-000001", + "value": "100" + }, + { + "tokenIdentifier": "str:SFT-123", + "nonce": "5", + "value": "10" + } + ], + "function": "payment_array_3", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:incorrect number of ESDT transfers", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "payment-array-ok", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:TOK-000001", + "value": "100" + }, + { + "tokenIdentifier": "str:EGLD-000000", + "value": "400" + }, + { + "tokenIdentifier": "str:SFT-123", + "nonce": "5", + "value": "10" + } + ], + "function": "payment_array_3", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "nested:str:TOK-000001|u64:0|biguint:100", + "nested:str:EGLD-000000|u64:0|biguint:400", + "nested:str:SFT-123|u64:5|biguint:10" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} \ No newline at end of file diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json index 28e667b322..45d92e9fa7 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json @@ -47,11 +47,6 @@ "tokenIdentifier": "str:SFT-123", "nonce": "5", "value": "10" - }, - { - "tokenIdentifier": "str:EGLD-000000", - "nonce": "0", - "value": "120" } ], "function": "payment_multiple", @@ -64,8 +59,7 @@ [ "nested:str:TOK-123456|u64:0|biguint:100|", "nested:str:OTHERTOK-123456|u64:0|biguint:400", - "nested:str:SFT-123|u64:5|biguint:10", - "nested:str:EGLD-000000|u64:0|biguint:120" + "nested:str:SFT-123|u64:5|biguint:10" ] ], "status": "", @@ -75,4 +69,4 @@ } } ] -} \ No newline at end of file +} diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json new file mode 100644 index 0000000000..28e667b322 --- /dev/null +++ b/contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json @@ -0,0 +1,78 @@ +{ + "name": "payable", + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:payable-features": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/payable-features.mxsc.json" + }, + "address:an-account": { + "nonce": "0", + "balance": "10000", + "esdt": { + "str:TOK-123456": "1000", + "str:OTHERTOK-123456": "500", + "str:SFT-123": { + "instances": [ + { + "nonce": "5", + "balance": "20" + } + ] + } + } + } + } + }, + { + "step": "scCall", + "id": "payment-multiple", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:TOK-123456", + "value": "100" + }, + { + "tokenIdentifier": "str:OTHERTOK-123456", + "value": "400" + }, + { + "tokenIdentifier": "str:SFT-123", + "nonce": "5", + "value": "10" + }, + { + "tokenIdentifier": "str:EGLD-000000", + "nonce": "0", + "value": "120" + } + ], + "function": "payment_multiple", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + [ + "nested:str:TOK-123456|u64:0|biguint:100|", + "nested:str:OTHERTOK-123456|u64:0|biguint:400", + "nested:str:SFT-123|u64:5|biguint:10", + "nested:str:EGLD-000000|u64:0|biguint:120" + ] + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} \ No newline at end of file From 9fa14b549e47f2251887f7ea47b4dd4329e14378 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sun, 22 Dec 2024 18:02:54 +0200 Subject: [PATCH 102/133] payable attribute - allow `#[payable]` --- framework/derive/src/parse/attributes/payable_attr.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/framework/derive/src/parse/attributes/payable_attr.rs b/framework/derive/src/parse/attributes/payable_attr.rs index 73293719d0..bdc38d8800 100644 --- a/framework/derive/src/parse/attributes/payable_attr.rs +++ b/framework/derive/src/parse/attributes/payable_attr.rs @@ -27,7 +27,8 @@ impl PayableAttribute { fn extract_token_identifier(attr: &syn::Attribute) -> Option { match attr.meta.clone() { syn::Meta::Path(_) => { - panic!("attribute needs 1 string argument: Replace with #[payable(\"*\")] or #[payable(\"EGLD\")]") + // #[payable] + Some("*".to_owned()) }, syn::Meta::List(list) => { let mut iter = list.tokens.into_iter(); From 0fad48a14d429b93223b36e854409d7fbcb4715f Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sun, 22 Dec 2024 18:03:38 +0200 Subject: [PATCH 103/133] payable attribute - `#[payable]` in examples --- .../bonding-curve-contract/src/bonding_curve_contract.rs | 6 +++--- .../examples/crowdfunding-esdt/src/crowdfunding_esdt.rs | 2 +- contracts/examples/digital-cash/src/pay_fee_and_fund.rs | 4 ++-- contracts/examples/digital-cash/src/signature_operations.rs | 2 +- .../esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs | 2 +- contracts/examples/fractional-nfts/src/fractional_nfts.rs | 4 ++-- contracts/examples/lottery-esdt/src/lottery.rs | 2 +- contracts/examples/multisig/src/multisig.rs | 2 +- contracts/examples/nft-minter/src/nft_module.rs | 2 +- contracts/examples/nft-subscription/src/lib.rs | 6 +++--- contracts/examples/order-book/pair/src/lib.rs | 4 ++-- .../rewards-distribution/src/rewards_distribution.rs | 4 ++-- contracts/examples/seed-nft-minter/src/nft_module.rs | 2 +- 13 files changed, 21 insertions(+), 21 deletions(-) diff --git a/contracts/examples/bonding-curve-contract/src/bonding_curve_contract.rs b/contracts/examples/bonding-curve-contract/src/bonding_curve_contract.rs index 6ab29068d3..490eb4bb42 100644 --- a/contracts/examples/bonding-curve-contract/src/bonding_curve_contract.rs +++ b/contracts/examples/bonding-curve-contract/src/bonding_curve_contract.rs @@ -20,13 +20,13 @@ pub trait Contract: #[init] fn init(&self) {} - #[payable("*")] + #[payable] #[endpoint(sellToken)] fn sell_token_endpoint(&self) { self.sell_token::>(); } - #[payable("*")] + #[payable] #[endpoint(buyToken)] fn buy_token_endpoint( &self, @@ -42,7 +42,7 @@ pub trait Contract: } #[endpoint(deposit)] - #[payable("*")] + #[payable] fn deposit_endpoint(&self, payment_token: OptionalValue) { self.deposit::>(payment_token) } diff --git a/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs b/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs index d47e256f08..1c7e3acebd 100644 --- a/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs +++ b/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs @@ -29,7 +29,7 @@ pub trait Crowdfunding { } #[endpoint] - #[payable("*")] + #[payable] fn fund(&self) { let (token, _, payment) = self.call_value().egld_or_single_esdt().into_tuple(); diff --git a/contracts/examples/digital-cash/src/pay_fee_and_fund.rs b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs index edff9df18e..3815ea38cc 100644 --- a/contracts/examples/digital-cash/src/pay_fee_and_fund.rs +++ b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs @@ -5,7 +5,7 @@ use crate::{constants::*, helpers, storage}; #[multiversx_sc::module] pub trait PayFeeAndFund: storage::StorageModule + helpers::HelpersModule { #[endpoint(payFeeAndFundESDT)] - #[payable("*")] + #[payable] fn pay_fee_and_fund_esdt(&self, address: ManagedAddress, valability: u64) { let mut payments = self.call_value().all_esdt_transfers().clone(); let fee = EgldOrEsdtTokenPayment::from(payments.get(0).clone()); @@ -32,7 +32,7 @@ pub trait PayFeeAndFund: storage::StorageModule + helpers::HelpersModule { } #[endpoint] - #[payable("*")] + #[payable] fn fund(&self, address: ManagedAddress, valability: u64) { require!(!self.deposit(&address).is_empty(), FEES_NOT_COVERED_ERR_MSG); let deposit_mapper = self.deposit(&address).get(); diff --git a/contracts/examples/digital-cash/src/signature_operations.rs b/contracts/examples/digital-cash/src/signature_operations.rs index 9c68951f05..2c31701a00 100644 --- a/contracts/examples/digital-cash/src/signature_operations.rs +++ b/contracts/examples/digital-cash/src/signature_operations.rs @@ -92,7 +92,7 @@ pub trait SignatureOperationsModule: storage::StorageModule + helpers::HelpersMo } #[endpoint] - #[payable("*")] + #[payable] fn forward( &self, address: ManagedAddress, diff --git a/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs b/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs index 5967c8feaa..b885ec371f 100644 --- a/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs +++ b/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs @@ -43,7 +43,7 @@ pub trait EsdtTransferWithFee { self.tx().to(ToCaller).payment(fees).transfer(); } - #[payable("*")] + #[payable] #[endpoint] fn transfer(&self, address: ManagedAddress) { require!( diff --git a/contracts/examples/fractional-nfts/src/fractional_nfts.rs b/contracts/examples/fractional-nfts/src/fractional_nfts.rs index 2b9844449a..fea51e2431 100644 --- a/contracts/examples/fractional-nfts/src/fractional_nfts.rs +++ b/contracts/examples/fractional-nfts/src/fractional_nfts.rs @@ -47,7 +47,7 @@ pub trait FractionalNfts: default_issue_callbacks::DefaultIssueCallbacksModule { .async_call_and_exit(); } - #[payable("*")] + #[payable] #[endpoint(fractionalizeNFT)] fn fractionalize_nft( &self, @@ -97,7 +97,7 @@ pub trait FractionalNfts: default_issue_callbacks::DefaultIssueCallbacksModule { .transfer(); } - #[payable("*")] + #[payable] #[endpoint(unFractionalizeNFT)] fn unfractionalize_nft(&self) { let fractional_payment = self.call_value().single_esdt(); diff --git a/contracts/examples/lottery-esdt/src/lottery.rs b/contracts/examples/lottery-esdt/src/lottery.rs index 5c573ef651..026710d5c7 100644 --- a/contracts/examples/lottery-esdt/src/lottery.rs +++ b/contracts/examples/lottery-esdt/src/lottery.rs @@ -166,7 +166,7 @@ pub trait Lottery { } #[endpoint] - #[payable("*")] + #[payable] fn buy_ticket(&self, lottery_name: ManagedBuffer) { let (token_identifier, payment) = self.call_value().egld_or_single_fungible_esdt(); diff --git a/contracts/examples/multisig/src/multisig.rs b/contracts/examples/multisig/src/multisig.rs index d1e177df02..4c32bb8f0a 100644 --- a/contracts/examples/multisig/src/multisig.rs +++ b/contracts/examples/multisig/src/multisig.rs @@ -49,7 +49,7 @@ pub trait Multisig: } /// Allows the contract to receive funds even if it is marked as unpayable in the protocol. - #[payable("*")] + #[payable] #[endpoint] fn deposit(&self) {} diff --git a/contracts/examples/nft-minter/src/nft_module.rs b/contracts/examples/nft-minter/src/nft_module.rs index ab4fd22504..6629c22d11 100644 --- a/contracts/examples/nft-minter/src/nft_module.rs +++ b/contracts/examples/nft-minter/src/nft_module.rs @@ -59,7 +59,7 @@ pub trait NftModule { // endpoints - #[payable("*")] + #[payable] #[endpoint(buyNft)] fn buy_nft(&self, nft_nonce: u64) { let payment = self.call_value().egld_or_single_esdt(); diff --git a/contracts/examples/nft-subscription/src/lib.rs b/contracts/examples/nft-subscription/src/lib.rs index 210a20020f..beca5ac5bf 100644 --- a/contracts/examples/nft-subscription/src/lib.rs +++ b/contracts/examples/nft-subscription/src/lib.rs @@ -46,7 +46,7 @@ pub trait NftSubscription: .transfer(); } - #[payable("*")] + #[payable] #[endpoint] fn update_attributes(&self, attributes: ManagedBuffer) { let payment = self.call_value().single_esdt(); @@ -65,7 +65,7 @@ pub trait NftSubscription: .transfer(); } - #[payable("*")] + #[payable] #[endpoint] fn renew(&self, duration: u64) { let payment = self.call_value().single_esdt(); @@ -84,7 +84,7 @@ pub trait NftSubscription: .transfer(); } - #[payable("*")] + #[payable] #[endpoint] fn cancel(&self) { let payment = self.call_value().single_esdt(); diff --git a/contracts/examples/order-book/pair/src/lib.rs b/contracts/examples/order-book/pair/src/lib.rs index 69e3a9f8c5..d1e8a2aa21 100644 --- a/contracts/examples/order-book/pair/src/lib.rs +++ b/contracts/examples/order-book/pair/src/lib.rs @@ -24,7 +24,7 @@ pub trait Pair: self.second_token_id().set_if_empty(&second_token_id); } - #[payable("*")] + #[payable] #[endpoint(createBuyOrder)] fn create_buy_order_endpoint(&self, params: OrderInputParams) { self.require_global_op_not_ongoing(); @@ -34,7 +34,7 @@ pub trait Pair: self.create_order(payment, params, common::OrderType::Buy); } - #[payable("*")] + #[payable] #[endpoint(createSellOrder)] fn create_sell_order_endpoint(&self, params: OrderInputParams) { self.require_global_op_not_ongoing(); diff --git a/contracts/examples/rewards-distribution/src/rewards_distribution.rs b/contracts/examples/rewards-distribution/src/rewards_distribution.rs index ecbf2b7d7c..48ba549a9e 100644 --- a/contracts/examples/rewards-distribution/src/rewards_distribution.rs +++ b/contracts/examples/rewards-distribution/src/rewards_distribution.rs @@ -57,7 +57,7 @@ pub trait RewardsDistribution: self.brackets().set(brackets); } - #[payable("*")] + #[payable] #[endpoint(depositRoyalties)] fn deposit_royalties(&self) { let payment = self.call_value().egld_or_single_esdt(); @@ -247,7 +247,7 @@ pub trait RewardsDistribution: ); } - #[payable("*")] + #[payable] #[endpoint(claimRewards)] fn claim_rewards( &self, diff --git a/contracts/examples/seed-nft-minter/src/nft_module.rs b/contracts/examples/seed-nft-minter/src/nft_module.rs index 3580ecedb5..8c271e5686 100644 --- a/contracts/examples/seed-nft-minter/src/nft_module.rs +++ b/contracts/examples/seed-nft-minter/src/nft_module.rs @@ -38,7 +38,7 @@ pub trait NftModule: // endpoints - #[payable("*")] + #[payable] #[endpoint(buyNft)] fn buy_nft(&self, nft_nonce: u64) { let payment = self.call_value().egld_or_single_esdt(); From 1e0d401281a34464b2b86e82786f3c3cf629f0f7 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sun, 22 Dec 2024 18:10:09 +0200 Subject: [PATCH 104/133] payable attribute - refactoring --- .../derive/src/parse/attributes/payable_attr.rs | 8 ++++---- framework/derive/src/parse/method_parse.rs | 4 ++-- framework/derive/src/parse/payable_parse.rs | 14 +++++--------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/framework/derive/src/parse/attributes/payable_attr.rs b/framework/derive/src/parse/attributes/payable_attr.rs index bdc38d8800..6c0241848f 100644 --- a/framework/derive/src/parse/attributes/payable_attr.rs +++ b/framework/derive/src/parse/attributes/payable_attr.rs @@ -3,7 +3,7 @@ use crate::parse::attributes::util::{clean_string, is_first_char_numeric}; use super::attr_names::*; pub struct PayableAttribute { - pub identifier: Option, + pub identifier: String, } impl PayableAttribute { @@ -24,11 +24,11 @@ impl PayableAttribute { /// Current implementation only works with 1 token name. /// Might be extended in the future. -fn extract_token_identifier(attr: &syn::Attribute) -> Option { +fn extract_token_identifier(attr: &syn::Attribute) -> String { match attr.meta.clone() { syn::Meta::Path(_) => { // #[payable] - Some("*".to_owned()) + "*".to_owned() }, syn::Meta::List(list) => { let mut iter = list.tokens.into_iter(); @@ -61,7 +61,7 @@ fn extract_token_identifier(attr: &syn::Attribute) -> Option { iter.next().is_none(), "too many tokens in attribute argument" ); - Some(ticker) + ticker }, syn::Meta::NameValue(_) => panic!( "attribute can not be name value. attribute needs 1 string argument: \"*\" or \"EGLD\"" diff --git a/framework/derive/src/parse/method_parse.rs b/framework/derive/src/parse/method_parse.rs index e299912cdd..b5fa90b54d 100644 --- a/framework/derive/src/parse/method_parse.rs +++ b/framework/derive/src/parse/method_parse.rs @@ -16,7 +16,7 @@ use super::{ process_title_attribute, process_upgrade_attribute, process_view_attribute, }; pub struct MethodAttributesPass1 { - pub method_name: String, + pub _method_name: String, pub payable: MethodPayableMetadata, pub only_owner: bool, pub only_admin: bool, @@ -34,7 +34,7 @@ pub fn process_method(m: &syn::TraitItemFn, trait_attributes: &TraitProperties) }; let mut first_pass_data = MethodAttributesPass1 { - method_name: m.sig.ident.to_string(), + _method_name: m.sig.ident.to_string(), payable: MethodPayableMetadata::NotPayable, only_owner: trait_attributes.only_owner, only_admin: trait_attributes.only_admin, diff --git a/framework/derive/src/parse/payable_parse.rs b/framework/derive/src/parse/payable_parse.rs index 91deba4509..99e6c8e17b 100644 --- a/framework/derive/src/parse/payable_parse.rs +++ b/framework/derive/src/parse/payable_parse.rs @@ -5,15 +5,11 @@ pub fn process_payable_attribute( attr: &syn::Attribute, pass_1_data: &mut MethodAttributesPass1, ) -> bool { - PayableAttribute::parse(attr).map(|payable_attr| { - if let Some(identifier) = payable_attr.identifier { - pass_1_data.payable = parse_payable_identifier(identifier.as_str()); - } else { - panic!( - "Endpoint `payable` attribute requires one argument. Replace with `#[payable(\"*\")]` or `#[payable(\"EGLD\")]`. Method name: {}", - &pass_1_data.method_name); - } - }).is_some() + PayableAttribute::parse(attr) + .map(|payable_attr| { + pass_1_data.payable = parse_payable_identifier(&payable_attr.identifier); + }) + .is_some() } fn parse_payable_identifier(identifier: &str) -> MethodPayableMetadata { From ecca7b961f63f359beda358810747df093f03145 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 27 Dec 2024 10:05:09 +0200 Subject: [PATCH 105/133] payable features interactor - initial commit --- Cargo.lock | 13 +++ Cargo.toml | 1 + .../payable-features/interactor/.gitignore | 5 + .../payable-features/interactor/Cargo.toml | 30 ++++++ .../payable-features/interactor/config.toml | 7 ++ .../interactor/src/payable_interactor.rs | 95 +++++++++++++++++++ .../interactor/src/payable_interactor_cli.rs | 19 ++++ .../src/payable_interactor_config.rs | 49 ++++++++++ .../interactor/src/payable_interactor_main.rs | 6 ++ .../src/payable_interactor_state.rs | 50 ++++++++++ .../payable-features/sc-config.toml | 4 + .../payable-features/src/payable_features.rs | 6 ++ .../src/payable_features_proxy.rs | 8 ++ .../payable-features/wasm/src/lib.rs | 5 +- .../wrappers/call_value_wrapper.rs | 2 +- 15 files changed, 297 insertions(+), 3 deletions(-) create mode 100644 contracts/feature-tests/payable-features/interactor/.gitignore create mode 100644 contracts/feature-tests/payable-features/interactor/Cargo.toml create mode 100644 contracts/feature-tests/payable-features/interactor/config.toml create mode 100644 contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs create mode 100644 contracts/feature-tests/payable-features/interactor/src/payable_interactor_cli.rs create mode 100644 contracts/feature-tests/payable-features/interactor/src/payable_interactor_config.rs create mode 100644 contracts/feature-tests/payable-features/interactor/src/payable_interactor_main.rs create mode 100644 contracts/feature-tests/payable-features/interactor/src/payable_interactor_state.rs create mode 100644 contracts/feature-tests/payable-features/sc-config.toml diff --git a/Cargo.lock b/Cargo.lock index 3a07185582..fa83aca684 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -2981,6 +2981,19 @@ dependencies = [ "payable-features", ] +[[package]] +name = "payable-interactor" +version = "0.0.0" +dependencies = [ + "clap", + "multiversx-sc-snippets", + "payable-features", + "serde", + "serial_test", + "tokio", + "toml", +] + [[package]] name = "payload-macro-generator" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 3cc34e3bd4..10c6723126 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -181,6 +181,7 @@ members = [ "contracts/feature-tests/panic-message-features", "contracts/feature-tests/panic-message-features/meta", "contracts/feature-tests/payable-features", + "contracts/feature-tests/payable-features/interactor", "contracts/feature-tests/payable-features/meta", "contracts/feature-tests/rust-snippets-generator-test", "contracts/feature-tests/rust-snippets-generator-test/meta", diff --git a/contracts/feature-tests/payable-features/interactor/.gitignore b/contracts/feature-tests/payable-features/interactor/.gitignore new file mode 100644 index 0000000000..88af50ac47 --- /dev/null +++ b/contracts/feature-tests/payable-features/interactor/.gitignore @@ -0,0 +1,5 @@ +# Pem files are used for interactions, but shouldn't be committed +*.pem + +# Temporary storage of deployed contract address, so we can preserve the context between executions. +state.toml diff --git a/contracts/feature-tests/payable-features/interactor/Cargo.toml b/contracts/feature-tests/payable-features/interactor/Cargo.toml new file mode 100644 index 0000000000..bf611a1c81 --- /dev/null +++ b/contracts/feature-tests/payable-features/interactor/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "payable-interactor" +version = "0.0.0" +authors = ["MultiversX "] +edition = "2021" +publish = false + +[[bin]] +name = "payable-interactor" +path = "src/payable_interactor_main.rs" + +[lib] +path = "src/payable_interactor.rs" + +[dependencies.payable-features] +path = ".." + +[dependencies.multiversx-sc-snippets] +version = "0.54.6" +path = "../../../../framework/snippets" + +[dependencies] +clap = { version = "4.4.7", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } +toml = "0.8.6" +tokio = { version = "1.24" } +serial_test = { version = "3.2.0" } + +[features] +chain-simulator-tests = [] diff --git a/contracts/feature-tests/payable-features/interactor/config.toml b/contracts/feature-tests/payable-features/interactor/config.toml new file mode 100644 index 0000000000..97acd5a5c6 --- /dev/null +++ b/contracts/feature-tests/payable-features/interactor/config.toml @@ -0,0 +1,7 @@ + +# chain_type = 'simulator' +# gateway_uri = 'http://localhost:8085' + +chain_type = 'real' +gateway_uri = 'https://devnet-gateway.multiversx.com' + diff --git a/contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs b/contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs new file mode 100644 index 0000000000..aac950e844 --- /dev/null +++ b/contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs @@ -0,0 +1,95 @@ +mod payable_interactor_cli; +mod payable_interactor_config; +mod payable_interactor_state; + +use payable_features::payable_features_proxy; +pub use payable_interactor_config::Config; +use payable_interactor_state::State; +use clap::Parser; + +use multiversx_sc_snippets::imports::*; + +const CODE_PATH: MxscPath = MxscPath::new("../output/payable-features.mxsc.json"); + +pub async fn adder_cli() { + env_logger::init(); + + let config = Config::load_config(); + + let mut basic_interact = PayableInteract::new(config).await; + + let cli = payable_interactor_cli::InteractCli::parse(); + match &cli.command { + Some(payable_interactor_cli::InteractCliCommand::Deploy) => { + basic_interact.deploy().await; + }, + Some(payable_interactor_cli::InteractCliCommand::AllTransfers) => { + basic_interact.check_all_transfers().await; + }, + None => {}, + } +} + +pub struct PayableInteract { + pub interactor: Interactor, + pub sc_owner_address: Bech32Address, + pub wallet_address: Bech32Address, + pub state: State, +} + +impl PayableInteract { + pub async fn new(config: Config) -> Self { + let mut interactor = Interactor::new(config.gateway_uri()) + .await + .use_chain_simulator(config.use_chain_simulator()); + + let sc_owner_address = interactor.register_wallet(test_wallets::heidi()).await; + let wallet_address = interactor.register_wallet(test_wallets::ivan()).await; + + interactor.generate_blocks(30u64).await.unwrap(); + + PayableInteract { + interactor, + sc_owner_address: sc_owner_address.into(), + wallet_address: wallet_address.into(), + state: State::load_state(), + } + } + + pub async fn deploy(&mut self) { + let new_address = self + .interactor + .tx() + .from(&self.sc_owner_address.clone()) + .gas(30_000_000) + .typed(payable_features_proxy::PayableFeaturesProxy) + .init() + .code(CODE_PATH) + .returns(ReturnsNewBech32Address) + .run() + .await; + + println!("new address: {new_address}"); + self.state.set_adder_address(new_address); + } + + pub async fn check_all_transfers(&mut self) { + let mut payment = MultiEsdtPayment::new(); + payment.push(EsdtTokenPayment::new("EGLD-000000".into(), 0, 1_0000u64.into())); + payment.push(EsdtTokenPayment::new("EGLD-000000".into(), 0, 2_0000u64.into())); + + let result = self.interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_adder_address()) + .gas(6_000_000u64) + .typed(payable_features_proxy::PayableFeaturesProxy) + .payable_all_transfers() + .multi_esdt(payment) + .returns(ReturnsResult) + .run() + .await; + + println!("Result: {result:?}"); + } +} diff --git a/contracts/feature-tests/payable-features/interactor/src/payable_interactor_cli.rs b/contracts/feature-tests/payable-features/interactor/src/payable_interactor_cli.rs new file mode 100644 index 0000000000..b1d38ddba5 --- /dev/null +++ b/contracts/feature-tests/payable-features/interactor/src/payable_interactor_cli.rs @@ -0,0 +1,19 @@ +use clap::{Parser, Subcommand}; + +/// Adder Interact CLI +#[derive(Default, PartialEq, Eq, Debug, Parser)] +#[command(version, about)] +#[command(propagate_version = true)] +pub struct InteractCli { + #[command(subcommand)] + pub command: Option, +} + +/// Adder Interact CLI Commands +#[derive(Clone, PartialEq, Eq, Debug, Subcommand)] +pub enum InteractCliCommand { + #[command(name = "deploy", about = "Deploy contract")] + Deploy, + #[command(name = "at", about = "Check all transfers")] + AllTransfers, +} diff --git a/contracts/feature-tests/payable-features/interactor/src/payable_interactor_config.rs b/contracts/feature-tests/payable-features/interactor/src/payable_interactor_config.rs new file mode 100644 index 0000000000..bd19da629d --- /dev/null +++ b/contracts/feature-tests/payable-features/interactor/src/payable_interactor_config.rs @@ -0,0 +1,49 @@ +use serde::Deserialize; +use std::io::Read; + +/// Config file +const CONFIG_FILE: &str = "config.toml"; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum ChainType { + Real, + Simulator, +} + +/// Adder Interact configuration +#[derive(Debug, Deserialize)] +pub struct Config { + pub gateway_uri: String, + pub chain_type: ChainType, +} + +impl Config { + // Deserializes config from file + pub fn load_config() -> Self { + let mut file = std::fs::File::open(CONFIG_FILE).unwrap(); + let mut content = String::new(); + file.read_to_string(&mut content).unwrap(); + toml::from_str(&content).unwrap() + } + + pub fn chain_simulator_config() -> Self { + Config { + gateway_uri: "http://localhost:8085".to_owned(), + chain_type: ChainType::Simulator, + } + } + + // Returns the gateway URI + pub fn gateway_uri(&self) -> &str { + &self.gateway_uri + } + + // Returns if chain type is chain simulator + pub fn use_chain_simulator(&self) -> bool { + match self.chain_type { + ChainType::Real => false, + ChainType::Simulator => true, + } + } +} diff --git a/contracts/feature-tests/payable-features/interactor/src/payable_interactor_main.rs b/contracts/feature-tests/payable-features/interactor/src/payable_interactor_main.rs new file mode 100644 index 0000000000..6d607fca05 --- /dev/null +++ b/contracts/feature-tests/payable-features/interactor/src/payable_interactor_main.rs @@ -0,0 +1,6 @@ +extern crate payable_interactor; + +#[tokio::main] +pub async fn main() { + payable_interactor::adder_cli().await; +} diff --git a/contracts/feature-tests/payable-features/interactor/src/payable_interactor_state.rs b/contracts/feature-tests/payable-features/interactor/src/payable_interactor_state.rs new file mode 100644 index 0000000000..bcab774134 --- /dev/null +++ b/contracts/feature-tests/payable-features/interactor/src/payable_interactor_state.rs @@ -0,0 +1,50 @@ +use multiversx_sc_snippets::imports::*; +use serde::{Deserialize, Serialize}; +use std::{ + io::{Read, Write}, + path::Path, +}; + +/// State file +const STATE_FILE: &str = "state.toml"; + +/// Adder Interact state +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct State { + adder_address: Option, +} + +impl State { + // Deserializes state from file + pub fn load_state() -> Self { + if Path::new(STATE_FILE).exists() { + let mut file = std::fs::File::open(STATE_FILE).unwrap(); + let mut content = String::new(); + file.read_to_string(&mut content).unwrap(); + toml::from_str(&content).unwrap() + } else { + Self::default() + } + } + + /// Sets the adder address + pub fn set_adder_address(&mut self, address: Bech32Address) { + self.adder_address = Some(address); + } + + /// Returns the adder contract + pub fn current_adder_address(&self) -> &Bech32Address { + self.adder_address + .as_ref() + .expect("no known adder contract, deploy first") + } +} + +impl Drop for State { + // Serializes state to file + fn drop(&mut self) { + let mut file = std::fs::File::create(STATE_FILE).unwrap(); + file.write_all(toml::to_string(self).unwrap().as_bytes()) + .unwrap(); + } +} diff --git a/contracts/feature-tests/payable-features/sc-config.toml b/contracts/feature-tests/payable-features/sc-config.toml new file mode 100644 index 0000000000..86b3debac9 --- /dev/null +++ b/contracts/feature-tests/payable-features/sc-config.toml @@ -0,0 +1,4 @@ +[settings] + +[[proxy]] +path = "src/payable_features_proxy.rs" diff --git a/contracts/feature-tests/payable-features/src/payable_features.rs b/contracts/feature-tests/payable-features/src/payable_features.rs index cf418efc0c..0ffcaa94ec 100644 --- a/contracts/feature-tests/payable-features/src/payable_features.rs +++ b/contracts/feature-tests/payable-features/src/payable_features.rs @@ -152,4 +152,10 @@ pub trait PayableFeatures { let token = self.call_value().single_esdt().token_identifier.clone(); (payment, token).into() } + + #[endpoint] + #[payable("*")] + fn payable_all_transfers(&self) -> ManagedVec { + self.call_value().all_transfers().clone() + } } diff --git a/contracts/feature-tests/payable-features/src/payable_features_proxy.rs b/contracts/feature-tests/payable-features/src/payable_features_proxy.rs index 7d6e020c89..936752a561 100644 --- a/contracts/feature-tests/payable-features/src/payable_features_proxy.rs +++ b/contracts/feature-tests/payable-features/src/payable_features_proxy.rs @@ -181,4 +181,12 @@ where .raw_call("payable_token_4") .original_result() } + + pub fn payable_all_transfers( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .raw_call("payable_all_transfers") + .original_result() + } } diff --git a/contracts/feature-tests/payable-features/wasm/src/lib.rs b/contracts/feature-tests/payable-features/wasm/src/lib.rs index 41f085e638..67b35b5de8 100644 --- a/contracts/feature-tests/payable-features/wasm/src/lib.rs +++ b/contracts/feature-tests/payable-features/wasm/src/lib.rs @@ -5,9 +5,9 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 15 +// Endpoints: 16 // Async Callback (empty): 1 -// Total number of exported functions: 17 +// Total number of exported functions: 18 #![no_std] @@ -33,6 +33,7 @@ multiversx_sc_wasm_adapter::endpoints! { payable_token_2 => payable_token_2 payable_token_3 => payable_token_3 payable_token_4 => payable_token_4 + payable_all_transfers => payable_all_transfers ) } diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 3304bfdcf2..211924accd 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -156,7 +156,7 @@ where } else { // clone all_esdt_transfers_unchecked -> all_transfers let all_transfers_unchecked_handle = self.all_esdt_transfers_unchecked(); - let _ = A::managed_type_impl().mb_set_slice(all_transfers_handle.clone(), 0, &[]); + let _ = A::managed_type_impl().mb_overwrite(all_transfers_handle.clone(), &[]); A::managed_type_impl() .mb_append(all_transfers_handle.clone(), all_transfers_unchecked_handle); } From 156c06b43454c115f1f89c04b01dc28037ea7d16 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 27 Dec 2024 18:22:57 +0200 Subject: [PATCH 106/133] mandos -> transaction functionality revamp + support for EGLD+ESDT --- .../interactor/src/payable_interactor.rs | 21 ++- .../wrappers/call_value_wrapper.rs | 2 +- .../src/scenario/model/transaction/tx_call.rs | 122 ++++++++++++++++++ .../src/scenario/model/transaction/tx_esdt.rs | 11 +- .../model/value/value_set_big_uint.rs | 7 + .../scenario/model/value/value_set_bytes.rs | 9 ++ .../interactor_scenario/interactor_sc_call.rs | 33 ++--- 7 files changed, 174 insertions(+), 31 deletions(-) diff --git a/contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs b/contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs index aac950e844..1b45535110 100644 --- a/contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs +++ b/contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs @@ -2,10 +2,10 @@ mod payable_interactor_cli; mod payable_interactor_config; mod payable_interactor_state; +use clap::Parser; use payable_features::payable_features_proxy; pub use payable_interactor_config::Config; use payable_interactor_state::State; -use clap::Parser; use multiversx_sc_snippets::imports::*; @@ -75,10 +75,19 @@ impl PayableInteract { pub async fn check_all_transfers(&mut self) { let mut payment = MultiEsdtPayment::new(); - payment.push(EsdtTokenPayment::new("EGLD-000000".into(), 0, 1_0000u64.into())); - payment.push(EsdtTokenPayment::new("EGLD-000000".into(), 0, 2_0000u64.into())); - - let result = self.interactor + payment.push(EsdtTokenPayment::new( + "EGLD-000000".into(), + 0, + 1_0000u64.into(), + )); + payment.push(EsdtTokenPayment::new( + "EGLD-000000".into(), + 0, + 2_0000u64.into(), + )); + + let result = self + .interactor .tx() .from(&self.wallet_address) .to(self.state.current_adder_address()) @@ -89,7 +98,7 @@ impl PayableInteract { .returns(ReturnsResult) .run() .await; - + println!("Result: {result:?}"); } } diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 211924accd..20bbcaab19 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -156,7 +156,7 @@ where } else { // clone all_esdt_transfers_unchecked -> all_transfers let all_transfers_unchecked_handle = self.all_esdt_transfers_unchecked(); - let _ = A::managed_type_impl().mb_overwrite(all_transfers_handle.clone(), &[]); + A::managed_type_impl().mb_overwrite(all_transfers_handle.clone(), &[]); A::managed_type_impl() .mb_append(all_transfers_handle.clone(), all_transfers_unchecked_handle); } diff --git a/framework/scenario/src/scenario/model/transaction/tx_call.rs b/framework/scenario/src/scenario/model/transaction/tx_call.rs index 547466032e..69b0ac594d 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_call.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_call.rs @@ -1,3 +1,8 @@ +use multiversx_sc::api::{ + ESDT_MULTI_TRANSFER_FUNC_NAME, ESDT_NFT_TRANSFER_FUNC_NAME, ESDT_TRANSFER_FUNC_NAME, +}; +use num_bigint::BigUint; + use crate::{ api::StaticApi, multiversx_sc::types::{ContractCall, EsdtTokenPayment}, @@ -127,4 +132,121 @@ impl TxCall { } contract_call } + + /// Converts call to builtin function ESDT transfer call, if necessary. + pub fn normalize(&self) -> TxCall { + let (function, arguments, to_self) = self.process_payments(); + TxCall { + from: self.from.clone(), + to: if to_self { + self.from.clone() + } else { + self.to.clone() + }, + egld_value: self.egld_value.clone(), + esdt_value: Vec::new(), + function, + arguments, + gas_limit: self.gas_limit.clone(), + gas_price: self.gas_price.clone(), + } + } + + fn process_payments(&self) -> (String, Vec, bool) { + assert!( + self.egld_value.is_zero() || self.esdt_value.is_empty(), + "Cannot have both EGLD and ESDT fields filled. To transfer EGLD and ESDT in the same transaction, represent EGLD as EGLD-000000 in the ESDTs."); + + match self.esdt_value.len() { + 0 => (self.function.clone(), self.arguments.clone(), false), + 1 => { + let payment = self.esdt_value.first().unwrap(); + if payment.is_egld() { + self.construct_multi_transfer_esdt_call() + } else if payment.nonce.value == 0 { + self.construct_single_transfer_fungible_call(payment) + } else { + self.construct_single_transfer_nft_call(payment) + } + }, + _ => self.construct_multi_transfer_esdt_call(), + } + } + + fn append_function_call_to_arguments(&self, arguments: &mut Vec) { + if !self.function.is_empty() { + arguments.push(BytesValue::from_str_expr(&self.function)); + } + for regular_arg in &self.arguments { + arguments.push(regular_arg.clone()) + } + } + + /// Constructs `ESDTTransfer` builtin function call. + pub(crate) fn construct_single_transfer_fungible_call( + &self, + payment: &TxESDT, + ) -> (String, Vec, bool) { + let mut arguments = Vec::new(); + arguments.push(payment.esdt_token_identifier.value.as_slice().into()); + arguments.push(top_encode_big_uint(&payment.esdt_value.value).into()); + self.append_function_call_to_arguments(&mut arguments); + + (ESDT_TRANSFER_FUNC_NAME.to_owned(), arguments, false) + } + + /// Constructs `ESDTNFTTransfer` builtin function call. + /// + /// `ESDTNFTTransfer` takes 4 arguments: + /// arg0 - token identifier + /// arg1 - nonce + /// arg2 - quantity to transfer + /// arg3 - destination address + pub(crate) fn construct_single_transfer_nft_call( + &self, + payment: &TxESDT, + ) -> (String, Vec, bool) { + let mut arguments = vec![ + payment.esdt_token_identifier.value.as_slice().into(), + top_encode_u64(payment.nonce.value).into(), + top_encode_big_uint(&payment.esdt_value.value).into(), + self.to.value.as_bytes().into(), // TODO: preserve representation + ]; + + self.append_function_call_to_arguments(&mut arguments); + + (ESDT_NFT_TRANSFER_FUNC_NAME.to_owned(), arguments, true) + } + + /// Constructs `MultiESDTNFTTransfer` builtin function call. + pub(crate) fn construct_multi_transfer_esdt_call(&self) -> (String, Vec, bool) { + let mut arguments = Vec::new(); + arguments.push(self.to.value.as_bytes().into()); // TODO: preserve representation + arguments.push(top_encode_u64(self.esdt_value.len() as u64).into()); + + for payment in &self.esdt_value { + arguments.push(payment.esdt_token_identifier.value.as_slice().into()); + arguments.push(top_encode_u64(payment.nonce.value).into()); + arguments.push(top_encode_big_uint(&payment.esdt_value.value).into()); + } + + self.append_function_call_to_arguments(&mut arguments); + + (ESDT_MULTI_TRANSFER_FUNC_NAME.to_owned(), arguments, true) + } +} + +// TODO: dedup +fn top_encode_u64(value: u64) -> Vec { + top_encode_big_uint(&BigUint::from(value)) +} + +// TODO: dedup +fn top_encode_big_uint(value: &BigUint) -> Vec { + use num_traits::Zero; + if value.is_zero() { + Vec::new() + } else { + value.to_bytes_be() + } } diff --git a/framework/scenario/src/scenario/model/transaction/tx_esdt.rs b/framework/scenario/src/scenario/model/transaction/tx_esdt.rs index 67ccf99956..e0bc36f962 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_esdt.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_esdt.rs @@ -1,4 +1,7 @@ -use multiversx_sc::{api::ManagedTypeApi, types::EsdtTokenPayment}; +use multiversx_sc::{ + api::ManagedTypeApi, + types::{EsdtTokenPayment, EGLD_000000_TOKEN_IDENTIFIER}, +}; use crate::{ scenario::model::{BigUintValue, BytesValue, U64Value}, @@ -15,6 +18,12 @@ pub struct TxESDT { pub esdt_value: BigUintValue, } +impl TxESDT { + pub fn is_egld(&self) -> bool { + self.esdt_token_identifier.value == EGLD_000000_TOKEN_IDENTIFIER.as_bytes() + } +} + impl InterpretableFrom for TxESDT { fn interpret_from(from: TxESDTRaw, context: &InterpreterContext) -> Self { TxESDT { diff --git a/framework/scenario/src/scenario/model/value/value_set_big_uint.rs b/framework/scenario/src/scenario/model/value/value_set_big_uint.rs index 003370509d..0246b72147 100644 --- a/framework/scenario/src/scenario/model/value/value_set_big_uint.rs +++ b/framework/scenario/src/scenario/model/value/value_set_big_uint.rs @@ -6,6 +6,7 @@ use crate::scenario_format::{ use crate::multiversx_sc::api::ManagedTypeApi; use num_bigint::BigUint; +use num_traits::Zero; use std::fmt; #[derive(Debug, Clone)] @@ -14,6 +15,12 @@ pub struct BigUintValue { pub original: ValueSubTree, } +impl BigUintValue { + pub fn is_zero(&self) -> bool { + self.value.is_zero() + } +} + impl InterpretableFrom for BigUintValue { fn interpret_from(from: ValueSubTree, context: &InterpreterContext) -> Self { let bytes = interpret_subtree(&from, context); diff --git a/framework/scenario/src/scenario/model/value/value_set_bytes.rs b/framework/scenario/src/scenario/model/value/value_set_bytes.rs index 160f30f75a..2b545b3c3d 100644 --- a/framework/scenario/src/scenario/model/value/value_set_bytes.rs +++ b/framework/scenario/src/scenario/model/value/value_set_bytes.rs @@ -24,12 +24,21 @@ impl BytesValue { } } + /// Creates a `0x...` expression directly. pub fn from_hex(hex_value: &str) -> Self { Self { value: hex::decode(hex_value).expect("could not decode hex value"), original: ValueSubTree::Str(format!("0x{hex_value}")), } } + + /// Creates a `str:...` expression directly. + pub fn from_str_expr(value: &str) -> Self { + Self { + value: value.as_bytes().to_owned(), + original: ValueSubTree::Str(format!("str:{value}")), + } + } } impl InterpretableFrom for BytesValue { diff --git a/framework/snippets/src/interactor/interactor_scenario/interactor_sc_call.rs b/framework/snippets/src/interactor/interactor_scenario/interactor_sc_call.rs index 86fd32a6f9..b18b03748c 100644 --- a/framework/snippets/src/interactor/interactor_scenario/interactor_sc_call.rs +++ b/framework/snippets/src/interactor/interactor_scenario/interactor_sc_call.rs @@ -1,7 +1,6 @@ use crate::{network_response, InteractorBase}; use log::info; use multiversx_sc_scenario::{ - api::StaticApi, scenario::ScenarioRunner, scenario_model::{ScCallStep, SetStateStep, TxCall}, }; @@ -58,10 +57,9 @@ where tx_hash } - #[allow(deprecated)] // TODO pub(crate) fn tx_call_to_blockchain_tx(&self, tx_call: &TxCall) -> Transaction { - let contract_call = tx_call.to_contract_call(); - let contract_call_tx_data = contract_call_to_tx_data(&contract_call); + let normalized = tx_call.normalize(); + let contract_call_tx_data = tx_call_to_tx_data(&normalized); let data = if contract_call_tx_data.is_empty() { None } else { @@ -70,11 +68,11 @@ where Transaction { nonce: 0, - value: contract_call.egld_payment.to_alloc().to_string(), - sender: tx_call.from.to_address().into(), - receiver: contract_call.basic.to.to_address().into(), + value: normalized.egld_value.value.to_string(), + sender: normalized.from.to_address().into(), + receiver: normalized.to.to_address().into(), gas_price: self.network_config.min_gas_price, - gas_limit: tx_call.gas_limit.value, + gas_limit: normalized.gas_limit.value, data, signature: None, chain_id: self.network_config.chain_id.clone(), @@ -84,22 +82,11 @@ where } } -#[allow(deprecated)] // TODO -fn contract_call_to_tx_data( - contract_call: &multiversx_sc_scenario::imports::ContractCallWithEgld, -) -> String { - let mut result = String::from_utf8( - contract_call - .basic - .function_call - .function_name - .to_boxed_bytes() - .into_vec(), - ) - .unwrap(); - for argument in contract_call.basic.function_call.arg_buffer.raw_arg_iter() { +fn tx_call_to_tx_data(tx_call: &TxCall) -> String { + let mut result = tx_call.function.clone(); + for argument in &tx_call.arguments { result.push('@'); - result.push_str(hex::encode(argument.to_boxed_bytes().as_slice()).as_str()); + result.push_str(hex::encode(argument.value.as_slice()).as_str()); } result } From 81902602673125ea89dcc499a22d7fdbed7547ac Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 27 Dec 2024 20:13:18 +0200 Subject: [PATCH 107/133] code dedup --- chain/vm/src/types.rs | 6 ++++-- .../src/scenario/model/transaction/tx_call.rs | 17 +---------------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/chain/vm/src/types.rs b/chain/vm/src/types.rs index 9ab80284a5..0a2eeac01d 100644 --- a/chain/vm/src/types.rs +++ b/chain/vm/src/types.rs @@ -10,11 +10,13 @@ pub type RawHandle = i32; use num_bigint::BigUint; use num_traits::Zero; -pub(crate) fn top_encode_u64(value: u64) -> Vec { +/// Helper function to quickly encode a u64 value, according to the MultiversX codec format. +pub fn top_encode_u64(value: u64) -> Vec { top_encode_big_uint(&BigUint::from(value)) } -pub(crate) fn top_encode_big_uint(value: &BigUint) -> Vec { +/// Helper function to quickly encode a BigUint value, according to the MultiversX codec format. +pub fn top_encode_big_uint(value: &BigUint) -> Vec { if value.is_zero() { Vec::new() } else { diff --git a/framework/scenario/src/scenario/model/transaction/tx_call.rs b/framework/scenario/src/scenario/model/transaction/tx_call.rs index 69b0ac594d..f96fdac7b0 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_call.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_call.rs @@ -1,7 +1,7 @@ +use multiversx_chain_vm::types::{top_encode_big_uint, top_encode_u64}; use multiversx_sc::api::{ ESDT_MULTI_TRANSFER_FUNC_NAME, ESDT_NFT_TRANSFER_FUNC_NAME, ESDT_TRANSFER_FUNC_NAME, }; -use num_bigint::BigUint; use crate::{ api::StaticApi, @@ -235,18 +235,3 @@ impl TxCall { (ESDT_MULTI_TRANSFER_FUNC_NAME.to_owned(), arguments, true) } } - -// TODO: dedup -fn top_encode_u64(value: u64) -> Vec { - top_encode_big_uint(&BigUint::from(value)) -} - -// TODO: dedup -fn top_encode_big_uint(value: &BigUint) -> Vec { - use num_traits::Zero; - if value.is_zero() { - Vec::new() - } else { - value.to_bytes_be() - } -} From 717e955cf70ea43ee0e6b59f67280e2c00b3fa70 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 30 Dec 2024 14:43:22 +0200 Subject: [PATCH 108/133] unified syntax - MultiEgldOrEsdtPayment, support for egld multi-payment --- .../interactor/src/payable_interactor.rs | 16 +- .../contract_call_convert.rs | 5 +- .../interaction/tx_data/function_call.rs | 6 +- .../base/src/types/interaction/tx_payment.rs | 5 +- .../tx_payment_multi_egld_or_esdt.rs | 150 ++++++++++++++++++ .../tx_payment/tx_payment_multi_esdt.rs | 9 +- .../tx_payment/tx_payment_single_esdt.rs | 8 +- .../tx_payment/tx_payment_single_esdt_ref.rs | 8 +- framework/base/src/types/managed/wrapped.rs | 4 +- .../wrapped/egld_or_esdt_token_payment.rs | 18 ++- .../managed/wrapped/esdt_token_payment.rs | 42 ++++- .../src/scenario/model/transaction/tx_esdt.rs | 14 +- 12 files changed, 243 insertions(+), 42 deletions(-) create mode 100644 framework/base/src/types/interaction/tx_payment/tx_payment_multi_egld_or_esdt.rs diff --git a/contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs b/contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs index 1b45535110..1096d14fbc 100644 --- a/contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs +++ b/contracts/feature-tests/payable-features/interactor/src/payable_interactor.rs @@ -74,17 +74,9 @@ impl PayableInteract { } pub async fn check_all_transfers(&mut self) { - let mut payment = MultiEsdtPayment::new(); - payment.push(EsdtTokenPayment::new( - "EGLD-000000".into(), - 0, - 1_0000u64.into(), - )); - payment.push(EsdtTokenPayment::new( - "EGLD-000000".into(), - 0, - 2_0000u64.into(), - )); + let mut payment = MultiEgldOrEsdtPayment::new(); + payment.push(EgldOrEsdtTokenPayment::egld_payment(1_0000u64.into())); + payment.push(EgldOrEsdtTokenPayment::egld_payment(2_0000u64.into())); let result = self .interactor @@ -94,7 +86,7 @@ impl PayableInteract { .gas(6_000_000u64) .typed(payable_features_proxy::PayableFeaturesProxy) .payable_all_transfers() - .multi_esdt(payment) + .payment(payment) .returns(ReturnsResult) .run() .await; diff --git a/framework/base/src/types/interaction/contract_call_legacy/contract_call_convert.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_convert.rs index 6a66c3e0f5..6b13a39bfc 100644 --- a/framework/base/src/types/interaction/contract_call_legacy/contract_call_convert.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_convert.rs @@ -78,7 +78,10 @@ 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.as_multi_egld_or_esdt_payment(), + ), explicit_gas_limit: self.basic.explicit_gas_limit, _return_type: PhantomData, }, diff --git a/framework/base/src/types/interaction/tx_data/function_call.rs b/framework/base/src/types/interaction/tx_data/function_call.rs index 7ebf20dd1a..1972e009f7 100644 --- a/framework/base/src/types/interaction/tx_data/function_call.rs +++ b/framework/base/src/types/interaction/tx_data/function_call.rs @@ -10,8 +10,8 @@ use crate::{ ESDT_TRANSFER_FUNC_NAME, }, types::{ - ContractCallNoPayment, EsdtTokenPayment, EsdtTokenPaymentRefs, ManagedAddress, - ManagedArgBuffer, ManagedBuffer, ManagedVec, MultiValueEncoded, TypedFunctionCall, + ContractCallNoPayment, EsdtTokenPaymentRefs, ManagedAddress, ManagedArgBuffer, + ManagedBuffer, MultiEgldOrEsdtPayment, MultiValueEncoded, TypedFunctionCall, }, }; @@ -196,7 +196,7 @@ where pub(crate) fn convert_to_multi_transfer_esdt_call( self, to: &ManagedAddress, - payments: &ManagedVec>, + payments: &MultiEgldOrEsdtPayment, ) -> FunctionCall { let mut result = FunctionCall::new(ESDT_MULTI_TRANSFER_FUNC_NAME) .argument(&to) diff --git a/framework/base/src/types/interaction/tx_payment.rs b/framework/base/src/types/interaction/tx_payment.rs index bed41cc775..d2d4fe5362 100644 --- a/framework/base/src/types/interaction/tx_payment.rs +++ b/framework/base/src/types/interaction/tx_payment.rs @@ -5,6 +5,7 @@ mod tx_payment_egld_or_esdt_refs; mod tx_payment_egld_or_multi_esdt; mod tx_payment_egld_or_multi_esdt_ref; mod tx_payment_egld_value; +mod tx_payment_multi_egld_or_esdt; mod tx_payment_multi_esdt; mod tx_payment_none; mod tx_payment_not_payable; @@ -20,7 +21,7 @@ pub use tx_payment_not_payable::NotPayable; use crate::{ api::ManagedTypeApi, - types::{BigUint, ManagedAddress, ManagedBuffer, MultiEsdtPayment}, + types::{BigUint, ManagedAddress, ManagedBuffer, MultiEgldOrEsdtPayment}, }; use super::{AnnotatedValue, FunctionCall, TxEnv, TxFrom, TxToSpecified}; @@ -118,7 +119,7 @@ where Api: ManagedTypeApi, { pub egld: Option>, - pub multi_esdt: MultiEsdtPayment, + pub multi_esdt: MultiEgldOrEsdtPayment, } impl Default for FullPaymentData diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_multi_egld_or_esdt.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_multi_egld_or_esdt.rs new file mode 100644 index 0000000000..149a052cea --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_multi_egld_or_esdt.rs @@ -0,0 +1,150 @@ +use core::ops::Deref; + +use crate::{ + api::{HandleConstraints, SendApi, SendApiImpl}, + types::{ + BigUint, ManagedAddress, ManagedRef, ManagedType, MultiEgldOrEsdtPayment, TxFrom, + TxToSpecified, + }, +}; + +use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; + +impl TxPayment for &MultiEgldOrEsdtPayment +where + Env: TxEnv, +{ + fn is_no_payment(&self, _env: &Env) -> bool { + self.is_empty() + } + + fn perform_transfer_execute( + self, + _env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + let _ = Env::Api::send_api_impl().multi_transfer_esdt_nft_execute( + to.get_handle().get_raw_handle(), + self.get_handle().get_raw_handle(), + gas_limit, + fc.function_name.get_handle().get_raw_handle(), + fc.arg_buffer.get_handle().get_raw_handle(), + ); + } + + 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); + 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.clone(), + } + } +} + +impl TxPayment for ManagedRef<'_, Env::Api, MultiEgldOrEsdtPayment> +where + Env: TxEnv, +{ + #[inline] + fn is_no_payment(&self, _env: &Env) -> bool { + self.deref().is_empty() + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + self.deref() + .perform_transfer_execute(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 MultiEgldOrEsdtPayment +where + Env: TxEnv, +{ + #[inline] + fn is_no_payment(&self, _env: &Env) -> bool { + self.is_empty() + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + (&self).perform_transfer_execute(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, + } + } +} 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 ab030362d2..7916cef015 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 @@ -62,7 +62,10 @@ where 0 => ().with_normalized(env, from, to, fc, f), 1 => self.get(0).as_refs().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); + 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) }), } @@ -71,7 +74,7 @@ where fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { FullPaymentData { egld: None, - multi_esdt: self.clone(), + multi_esdt: self.as_multi_egld_or_esdt_payment().clone(), } } } @@ -159,7 +162,7 @@ where fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { FullPaymentData { egld: None, - multi_esdt: self, + multi_esdt: self.into_multi_egld_or_esdt_payment(), } } } 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 9ace787df2..f52ed22345 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,4 @@ -use crate::types::{ - BigUint, EsdtTokenPayment, ManagedAddress, MultiEsdtPayment, TxFrom, TxToSpecified, -}; +use crate::types::{BigUint, EsdtTokenPayment, ManagedAddress, ManagedVec, TxFrom, TxToSpecified}; use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; @@ -45,7 +43,7 @@ where fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { FullPaymentData { egld: None, - multi_esdt: MultiEsdtPayment::from_single_item(self), + multi_esdt: ManagedVec::from_single_item(self.into_multi_egld_or_esdt_payment()), } } } @@ -91,7 +89,7 @@ where fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { FullPaymentData { egld: None, - multi_esdt: MultiEsdtPayment::from_single_item(self.clone()), + multi_esdt: ManagedVec::from_single_item(self.as_egld_or_esdt_payment().clone()), } } } diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_ref.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_ref.rs index 6aecb277a6..33a160df63 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_ref.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_ref.rs @@ -1,8 +1,6 @@ use crate::{ contract_base::SendRawWrapper, - types::{ - BigUint, EsdtTokenPaymentRefs, ManagedAddress, MultiEsdtPayment, TxFrom, TxToSpecified, - }, + types::{BigUint, EsdtTokenPaymentRefs, ManagedAddress, ManagedVec, TxFrom, TxToSpecified}, }; use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; @@ -74,7 +72,9 @@ where fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { FullPaymentData { egld: None, - multi_esdt: MultiEsdtPayment::from_single_item(self.to_owned_payment()), + multi_esdt: ManagedVec::from_single_item( + self.to_owned_payment().into_multi_egld_or_esdt_payment(), + ), } } } diff --git a/framework/base/src/types/managed/wrapped.rs b/framework/base/src/types/managed/wrapped.rs index 679890964b..6275c19ebc 100644 --- a/framework/base/src/types/managed/wrapped.rs +++ b/framework/base/src/types/managed/wrapped.rs @@ -32,7 +32,9 @@ mod traits; pub use big_uint::BigUint; pub use builder::*; pub use egld_or_esdt_token_identifier::{EgldOrEsdtTokenIdentifier, EGLD_000000_TOKEN_IDENTIFIER}; -pub use egld_or_esdt_token_payment::{EgldOrEsdtTokenPayment, EgldOrEsdtTokenPaymentRefs}; +pub use egld_or_esdt_token_payment::{ + EgldOrEsdtTokenPayment, EgldOrEsdtTokenPaymentRefs, MultiEgldOrEsdtPayment, +}; pub use egld_or_multi_esdt_payment::{EgldOrMultiEsdtPayment, EgldOrMultiEsdtPaymentRefs}; pub(crate) use encoded_managed_vec_item::EncodedManagedVecItem; pub use esdt_token_data::EsdtTokenData; diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs index 97a6d1261a..f8d9fa18e0 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs @@ -14,8 +14,8 @@ use crate::derive::type_abi; use super::{ managed_vec_item_read_from_payload_index, managed_vec_item_save_to_payload_index, - EsdtTokenPayment, EsdtTokenPaymentRefs, ManagedVecItem, ManagedVecItemPayloadBuffer, - ManagedVecRef, + EsdtTokenPayment, EsdtTokenPaymentRefs, ManagedVec, ManagedVecItem, + ManagedVecItemPayloadBuffer, ManagedVecRef, }; #[type_abi] @@ -26,13 +26,12 @@ pub struct EgldOrEsdtTokenPayment { pub amount: BigUint, } +/// Alias for a list of payments of EGLD or ESDT tokens. +pub type MultiEgldOrEsdtPayment = ManagedVec>; + impl EgldOrEsdtTokenPayment { pub fn no_payment() -> Self { - EgldOrEsdtTokenPayment { - token_identifier: EgldOrEsdtTokenIdentifier::egld(), - token_nonce: 0, - amount: BigUint::zero(), - } + Self::egld_payment(BigUint::zero()) } pub fn new( @@ -47,6 +46,11 @@ impl EgldOrEsdtTokenPayment { } } + /// A payment of token EGLD-000000. + pub fn egld_payment(amount: BigUint) -> Self { + Self::new(EgldOrEsdtTokenIdentifier::egld(), 0, amount) + } + /// Will convert to just ESDT or terminate execution if the token is EGLD. pub fn unwrap_esdt(self) -> EsdtTokenPayment { EsdtTokenPayment::new( diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 041ddd1f64..999b7b1cde 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -1,6 +1,9 @@ use crate::{ api::ManagedTypeApi, - types::{BigUint, EsdtTokenPaymentMultiValue, EsdtTokenType, ManagedVecItem, TokenIdentifier}, + types::{ + BigUint, EsdtTokenPaymentMultiValue, EsdtTokenType, ManagedType, ManagedVecItem, + TokenIdentifier, + }, }; use crate as multiversx_sc; // needed by the codec and TypeAbi generated code @@ -14,8 +17,9 @@ use crate::{ }; use super::{ - managed_vec_item_read_from_payload_index, managed_vec_item_save_to_payload_index, ManagedVec, - ManagedVecItemPayloadBuffer, ManagedVecRef, + managed_vec_item_read_from_payload_index, managed_vec_item_save_to_payload_index, + EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, ManagedVec, ManagedVecItemPayloadBuffer, + ManagedVecRef, MultiEgldOrEsdtPayment, }; #[type_abi] @@ -57,6 +61,22 @@ impl EsdtTokenPayment { pub fn into_tuple(self) -> (TokenIdentifier, u64, BigUint) { (self.token_identifier, self.token_nonce, self.amount) } + + /// Zero-cost conversion that loosens the EGLD restriction. + /// + /// It is always safe to do, since the 2 types are guaranteed to have the same layout. + pub fn as_egld_or_esdt_payment(&self) -> &EgldOrEsdtTokenPayment { + unsafe { core::mem::transmute(self) } + } + + /// Conversion that loosens the EGLD restriction. + pub fn into_multi_egld_or_esdt_payment(self) -> EgldOrEsdtTokenPayment { + EgldOrEsdtTokenPayment { + token_identifier: EgldOrEsdtTokenIdentifier::esdt(self.token_identifier), + token_nonce: self.token_nonce, + amount: self.amount, + } + } } impl From<(TokenIdentifier, u64, BigUint)> for EsdtTokenPayment { @@ -233,6 +253,22 @@ impl<'a, M: ManagedTypeApi> EsdtTokenPaymentRefs<'a, M> { } } +impl MultiEsdtPayment { + /// Zero-cost conversion that loosens the EGLD restriction. + /// + /// It is always safe to do, since the 2 types are guaranteed to have the same layout. + pub fn as_multi_egld_or_esdt_payment(&self) -> &MultiEgldOrEsdtPayment { + unsafe { core::mem::transmute(self) } + } + + /// Zero-cost conversion that loosens the EGLD restriction. + /// + /// It is always safe to do, since the 2 types are guaranteed to have the same layout. + pub fn into_multi_egld_or_esdt_payment(self) -> MultiEgldOrEsdtPayment { + unsafe { MultiEgldOrEsdtPayment::from_handle(self.forget_into_handle()) } + } +} + impl From<()> for MultiEsdtPayment { #[inline] fn from(_value: ()) -> Self { diff --git a/framework/scenario/src/scenario/model/transaction/tx_esdt.rs b/framework/scenario/src/scenario/model/transaction/tx_esdt.rs index e0bc36f962..3adecd7bce 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_esdt.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_esdt.rs @@ -1,6 +1,6 @@ use multiversx_sc::{ api::ManagedTypeApi, - types::{EsdtTokenPayment, EGLD_000000_TOKEN_IDENTIFIER}, + types::{EgldOrEsdtTokenPayment, EsdtTokenPayment, EGLD_000000_TOKEN_IDENTIFIER}, }; use crate::{ @@ -56,6 +56,18 @@ impl From> for TxESDT { } } +impl From> for TxESDT { + fn from(value: EgldOrEsdtTokenPayment) -> Self { + TxESDT { + esdt_token_identifier: BytesValue::from( + value.token_identifier.as_managed_buffer().to_vec(), + ), + nonce: U64Value::from(value.token_nonce), + esdt_value: BigUintValue::from(value.amount), + } + } +} + fn interpret_esdt_token_identifier( esdt_token_identifier: Option, context: &InterpreterContext, From 9c0b94e46f0b94f34a984d25ad030bf23d709296 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 30 Dec 2024 16:17:02 +0200 Subject: [PATCH 109/133] test rename --- .../tests/{contract_call_test.rs => tx_call_normalize.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename framework/scenario/tests/{contract_call_test.rs => tx_call_normalize.rs} (100%) diff --git a/framework/scenario/tests/contract_call_test.rs b/framework/scenario/tests/tx_call_normalize.rs similarity index 100% rename from framework/scenario/tests/contract_call_test.rs rename to framework/scenario/tests/tx_call_normalize.rs From 9f82268bf225449e1d0686bf11ac53a0ced8c9fb Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 30 Dec 2024 16:55:40 +0200 Subject: [PATCH 110/133] mandos -> transaction functionality tests --- .../src/scenario/model/transaction/tx_call.rs | 10 +++ framework/scenario/tests/tx_call_normalize.rs | 88 ++++++++++++++++++- .../interactor_scenario/interactor_sc_call.rs | 11 +-- 3 files changed, 98 insertions(+), 11 deletions(-) diff --git a/framework/scenario/src/scenario/model/transaction/tx_call.rs b/framework/scenario/src/scenario/model/transaction/tx_call.rs index f96fdac7b0..550f713683 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_call.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_call.rs @@ -234,4 +234,14 @@ impl TxCall { (ESDT_MULTI_TRANSFER_FUNC_NAME.to_owned(), arguments, true) } + + /// Creates the data field of the transaction represented by object. + pub fn compute_data_field(&self) -> String { + let mut result = self.function.clone(); + for argument in &self.arguments { + result.push('@'); + result.push_str(hex::encode(argument.value.as_slice()).as_str()); + } + result + } } diff --git a/framework/scenario/tests/tx_call_normalize.rs b/framework/scenario/tests/tx_call_normalize.rs index b6ff5ea1fb..821d202c6a 100644 --- a/framework/scenario/tests/tx_call_normalize.rs +++ b/framework/scenario/tests/tx_call_normalize.rs @@ -2,9 +2,95 @@ use multiversx_sc::api::ESDT_MULTI_TRANSFER_FUNC_NAME; use multiversx_sc_scenario::scenario_model::ScCallStep; use num_traits::Zero; +#[test] +fn test_tx_call_normalize_single_esdt_token_fungible() { + let tx = ScCallStep::new() + .from("address:sender") + .to("address:recipient") + .esdt_transfer("str:WEGLD-abcdef", 0, 10u32) + .function("func"); + + assert_eq!( + tx.tx.normalize().compute_data_field(), + "ESDTTransfer@5745474c442d616263646566@0a@66756e63", + ); +} + +#[test] +fn test_tx_call_normalize_single_esdt_token_non_fungible() { + let tx = ScCallStep::new() + .from("address:sender") + .to("address:recipient") + .esdt_transfer("str:SFT-abcdef", 1, 10u32) + .function("func"); + + assert_eq!( + tx.tx.normalize().compute_data_field(), + "ESDTNFTTransfer@5346542d616263646566@01@0a@726563697069656e745f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f@66756e63", + ); +} + +/// Only MultiESDTNFTTransfer supports EGLD-000000, so it is used even though we have a single token transfer. +#[test] +fn test_tx_call_normalize_single_egld_000000() { + let tx = ScCallStep::new() + .from("address:sender") + .to("address:recipient") + .esdt_transfer("str:EGLD-000000", 0, 10u32) + .function("func"); + + assert_eq!( + tx.tx.normalize().compute_data_field(), + "MultiESDTNFTTransfer@726563697069656e745f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f@01@45474c442d303030303030@@0a@66756e63", + ); +} + +#[test] +fn test_tx_call_normalize_multi_esdt_1() { + let tx = ScCallStep::new() + .from("address:sender") + .to("address:recipient") + .esdt_transfer("str:WEGLD-abcdef", 0, 10u32) + .esdt_transfer("str:USDC-abcdef", 0, 11u32); + + assert_eq!( + tx.tx.normalize().compute_data_field(), + "MultiESDTNFTTransfer@726563697069656e745f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f@02@5745474c442d616263646566@@0a@555344432d616263646566@@0b", + ); +} + +#[test] +fn test_tx_call_normalize_multi_esdt_2() { + let tx = ScCallStep::new() + .from("address:sender") + .to("address:recipient") + .esdt_transfer("str:WEGLD-abcdef", 0, 10u32) + .esdt_transfer("str:USDC-abcdef", 0, 11u32) + .function("func"); + + assert_eq!( + tx.tx.normalize().compute_data_field(), + "MultiESDTNFTTransfer@726563697069656e745f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f@02@5745474c442d616263646566@@0a@555344432d616263646566@@0b@66756e63", + ); +} + +#[test] +fn test_tx_call_normalize_single_esdt_token() { + let tx = ScCallStep::new() + .from("address:sender") + .to("address:recipient") + .esdt_transfer("str:WEGLD-abcdef", 0, 10u32) + .function("func"); + + assert_eq!( + tx.tx.normalize().compute_data_field(), + "ESDTTransfer@5745474c442d616263646566@0a@66756e63", + ); +} + #[test] #[allow(deprecated)] -fn test_contract_call_multi_esdt() { +fn test_contract_call_multi_esdt_deprecated() { let tx = ScCallStep::new() .from("address:sender") .to("address:recipient") diff --git a/framework/snippets/src/interactor/interactor_scenario/interactor_sc_call.rs b/framework/snippets/src/interactor/interactor_scenario/interactor_sc_call.rs index b18b03748c..8f3657b829 100644 --- a/framework/snippets/src/interactor/interactor_scenario/interactor_sc_call.rs +++ b/framework/snippets/src/interactor/interactor_scenario/interactor_sc_call.rs @@ -59,7 +59,7 @@ where pub(crate) fn tx_call_to_blockchain_tx(&self, tx_call: &TxCall) -> Transaction { let normalized = tx_call.normalize(); - let contract_call_tx_data = tx_call_to_tx_data(&normalized); + let contract_call_tx_data = normalized.compute_data_field(); let data = if contract_call_tx_data.is_empty() { None } else { @@ -81,12 +81,3 @@ where } } } - -fn tx_call_to_tx_data(tx_call: &TxCall) -> String { - let mut result = tx_call.function.clone(); - for argument in &tx_call.arguments { - result.push('@'); - result.push_str(hex::encode(argument.value.as_slice()).as_str()); - } - result -} From b03a851c03dc73fd05b17a52250eab690cbe0068 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 31 Dec 2024 00:05:04 +0200 Subject: [PATCH 111/133] egld multi payment call value mandos test --- chain/core/src/lib.rs | 3 + chain/vm/src/tx_mock/tx_cache_balance_util.rs | 5 + .../scenarios/payable_all_transfers.scen.json | 162 ++++++++++++++++++ .../tests/payable_scenario_go_test.rs | 5 + .../tests/payable_scenario_rs_test.rs | 5 + .../wrappers/call_value_wrapper.rs | 7 +- framework/base/src/types/managed/wrapped.rs | 2 +- .../wrapped/egld_or_esdt_token_identifier.rs | 3 +- .../src/scenario/model/transaction/tx_esdt.rs | 3 +- 9 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 contracts/feature-tests/payable-features/scenarios/payable_all_transfers.scen.json diff --git a/chain/core/src/lib.rs b/chain/core/src/lib.rs index 503f690d82..dbd636cc8c 100644 --- a/chain/core/src/lib.rs +++ b/chain/core/src/lib.rs @@ -7,3 +7,6 @@ pub mod types; /// Re-exported for convenience. pub use multiversx_sc_codec as codec; + +/// The equivalent ESDT token identifier for transferring EGLD, the native MultiversX token. +pub const EGLD_000000_TOKEN_IDENTIFIER: &str = "EGLD-000000"; diff --git a/chain/vm/src/tx_mock/tx_cache_balance_util.rs b/chain/vm/src/tx_mock/tx_cache_balance_util.rs index 97eb5fb1a5..c1a713ed4e 100644 --- a/chain/vm/src/tx_mock/tx_cache_balance_util.rs +++ b/chain/vm/src/tx_mock/tx_cache_balance_util.rs @@ -1,3 +1,4 @@ +use multiversx_chain_core::EGLD_000000_TOKEN_IDENTIFIER; use num_bigint::BigUint; use crate::{ @@ -109,6 +110,10 @@ impl TxCache { nonce: u64, value: &BigUint, ) -> Result<(), TxPanic> { + if esdt_token_identifier == EGLD_000000_TOKEN_IDENTIFIER.as_bytes() { + return self.transfer_egld_balance(from, to, value); + } + if !is_system_sc_address(from) && !is_system_sc_address(to) { let metadata = self.subtract_esdt_balance(from, esdt_token_identifier, nonce, value)?; self.increase_esdt_balance(to, esdt_token_identifier, nonce, value, metadata); diff --git a/contracts/feature-tests/payable-features/scenarios/payable_all_transfers.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_all_transfers.scen.json new file mode 100644 index 0000000000..8056c49898 --- /dev/null +++ b/contracts/feature-tests/payable-features/scenarios/payable_all_transfers.scen.json @@ -0,0 +1,162 @@ +{ + "name": "payable", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:payable-features": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/payable-features.mxsc.json" + }, + "address:an-account": { + "nonce": "0", + "balance": "10000", + "esdt": { + "str:TOK-123456": "1000", + "str:OTHERTOK-123456": "500", + "str:SFT-123": { + "instances": [ + { + "nonce": "5", + "balance": "20" + } + ] + } + } + } + } + }, + { + "step": "scCall", + "id": "payable_all_transfers-ZERO", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "function": "payable_all_transfers", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [""], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "payable_all_transfers-EGLD", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "egldValue": "1000", + "function": "payable_all_transfers", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + [ + "nested:str:EGLD|u64:0|biguint:1000" + ] + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "payable_all_transfers-multi-EGLD-2", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:EGLD-000000", + "value": "1001" + }, + { + "tokenIdentifier": "str:EGLD-000000", + "value": "1002" + } + ], + "function": "payable_all_transfers", + "arguments": [ + + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + [ + "nested:str:EGLD|u64:0|biguint:1001", + "nested:str:EGLD|u64:0|biguint:1002" + ] + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "payable_all_transfers-EGLD-with-ESDT", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:TOK-123456", + "value": "100" + }, + { + "tokenIdentifier": "str:EGLD-000000", + "value": "1005" + }, + { + "tokenIdentifier": "str:OTHERTOK-123456", + "value": "400" + }, + { + "tokenIdentifier": "str:SFT-123", + "nonce": "5", + "value": "10" + }, + { + "tokenIdentifier": "str:EGLD-000000", + "value": "1006" + } + ], + "function": "payable_all_transfers", + "arguments": [ + + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + [ + "nested:str:TOK-123456|u64:0|biguint:100|", + "nested:str:EGLD|u64:0|biguint:1005", + "nested:str:OTHERTOK-123456|u64:0|biguint:400", + "nested:str:SFT-123|u64:5|biguint:10", + "nested:str:EGLD|u64:0|biguint:1006" + ] + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} diff --git a/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs b/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs index a3ababd9c7..95be700ffa 100644 --- a/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs +++ b/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs @@ -9,6 +9,11 @@ fn call_value_check_go() { world().run("scenarios/call-value-check.scen.json"); } +#[test] +fn payable_all_transfers_go() { + world().run("scenarios/payable_all_transfers.scen.json"); +} + #[test] fn payable_any_1_go() { world().run("scenarios/payable_any_1.scen.json"); diff --git a/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs b/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs index 01b0ea567b..f3c4f752d9 100644 --- a/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs +++ b/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs @@ -15,6 +15,11 @@ fn call_value_check_rs() { world().run("scenarios/call-value-check.scen.json"); } +#[test] +fn payable_all_transfers_rs() { + world().run("scenarios/payable_all_transfers.scen.json"); +} + #[test] fn payable_any_1_rs() { world().run("scenarios/payable_any_1.scen.json"); diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 20bbcaab19..dea8246d00 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -1,5 +1,7 @@ use core::marker::PhantomData; +use multiversx_chain_core::EGLD_000000_TOKEN_IDENTIFIER; + use crate::{ api::{ const_handles, use_raw_handle, CallValueApi, CallValueApiImpl, ErrorApi, ErrorApiImpl, @@ -10,7 +12,7 @@ use crate::{ big_num_cmp::bi_gt_zero, BigInt, BigUint, ConstDecimals, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, EsdtTokenPayment, ManagedDecimal, ManagedRef, ManagedType, ManagedVec, ManagedVecItem, ManagedVecItemPayload, - ManagedVecPayloadIterator, ManagedVecRef, TokenIdentifier, EGLD_000000_TOKEN_IDENTIFIER, + ManagedVecPayloadIterator, ManagedVecRef, TokenIdentifier, }, }; @@ -148,9 +150,8 @@ where use_raw_handle(const_handles::MBUF_EGLD_000000), EGLD_000000_TOKEN_IDENTIFIER.as_bytes(), ); - let _ = A::managed_type_impl().mb_set_slice( + A::managed_type_impl().mb_overwrite( all_transfers_handle.clone(), - 0, &const_handles::EGLD_PAYMENT_PAYLOAD[..], ); } else { diff --git a/framework/base/src/types/managed/wrapped.rs b/framework/base/src/types/managed/wrapped.rs index 6275c19ebc..f32d17b47a 100644 --- a/framework/base/src/types/managed/wrapped.rs +++ b/framework/base/src/types/managed/wrapped.rs @@ -31,7 +31,7 @@ mod traits; pub use big_uint::BigUint; pub use builder::*; -pub use egld_or_esdt_token_identifier::{EgldOrEsdtTokenIdentifier, EGLD_000000_TOKEN_IDENTIFIER}; +pub use egld_or_esdt_token_identifier::EgldOrEsdtTokenIdentifier; pub use egld_or_esdt_token_payment::{ EgldOrEsdtTokenPayment, EgldOrEsdtTokenPaymentRefs, MultiEgldOrEsdtPayment, }; diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index 79b9977943..a2f14f6063 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -1,4 +1,5 @@ use alloc::string::ToString; +use multiversx_chain_core::EGLD_000000_TOKEN_IDENTIFIER; use crate::{ abi::{TypeAbi, TypeAbiFrom, TypeName}, @@ -12,8 +13,6 @@ use crate::{ types::{ManagedBuffer, ManagedRef, ManagedType, TokenIdentifier}, }; -pub const EGLD_000000_TOKEN_IDENTIFIER: &str = "EGLD-000000"; - /// Specialized type for handling either EGLD or ESDT token identifiers. /// /// Equivalent to a structure of the form diff --git a/framework/scenario/src/scenario/model/transaction/tx_esdt.rs b/framework/scenario/src/scenario/model/transaction/tx_esdt.rs index 3adecd7bce..e187f8f192 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_esdt.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_esdt.rs @@ -1,6 +1,7 @@ use multiversx_sc::{ api::ManagedTypeApi, - types::{EgldOrEsdtTokenPayment, EsdtTokenPayment, EGLD_000000_TOKEN_IDENTIFIER}, + chain_core::EGLD_000000_TOKEN_IDENTIFIER, + types::{EgldOrEsdtTokenPayment, EsdtTokenPayment}, }; use crate::{ From e480559e02547372e6feb80ebe7385c1986ec728 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 31 Dec 2024 09:44:31 +0200 Subject: [PATCH 112/133] temporarily removed test --- ...rwarder_send_esdt_multi_transfer.scen.json | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/contracts/feature-tests/composability/scenarios/forwarder_send_esdt_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_send_esdt_multi_transfer.scen.json index 80d7b639e2..4affc8a547 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_send_esdt_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_send_esdt_multi_transfer.scen.json @@ -178,31 +178,6 @@ "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } - }, - { - "step": "scCall", - "id": "EGLD-test", - "comment": "send all types", - "tx": { - "from": "address:a_user", - "to": "sc:forwarder", - "function": "send_esdt_direct_multi_transfer", - "arguments": [ - "address:a_user", - "str:EGLD", - "0", - "1000" - ], - "gasLimit": "80,000,000", - "gasPrice": "0" - }, - "expect": { - "out": [], - "status": "10", - "message": "str:insufficient funds", - "gas": "*", - "refund": "*" - } } ] } From a21448edf9bfc25e862053d30ca60eb51b243d38 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 31 Dec 2024 11:31:34 +0200 Subject: [PATCH 113/133] ManagedVec is_single_item, some refactor --- .../src/types/managed/wrapped/managed_vec.rs | 38 +++++++++++++------ framework/scenario/tests/managed_vec_test.rs | 17 ++++++++- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index ebb0f0d157..0b32d308e1 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -139,15 +139,20 @@ where self.byte_len() == 0 } - pub fn try_get(&self, index: usize) -> Option> { + /// Internal function that loads the payload for an item. + /// + /// Payload passed as mutable reference, to avoid copying of bytes around the stack. + fn load_item_payload(&self, index: usize, payload: &mut T::PAYLOAD) -> bool { let byte_index = index * T::payload_size(); - let mut payload = T::PAYLOAD::new_buffer(); - if self - .buffer + self.buffer .load_slice(byte_index, payload.payload_slice_mut()) .is_ok() - { + } + + pub fn try_get(&self, index: usize) -> Option> { + let mut payload = T::PAYLOAD::new_buffer(); + if self.load_item_payload(index, &mut payload) { unsafe { Some(T::borrow_from_payload(&payload)) } } else { None @@ -182,21 +187,30 @@ where } } + /// If it contains precisely one item, will return `Some` with a reference to that item. + /// + /// Will return `None` for zero or more than one item. + pub fn is_single_item(&self) -> Option> { + let mut payload = T::PAYLOAD::new_buffer(); + if self.len() == 1 { + let _ = self.load_item_payload(0, &mut payload); + unsafe { Some(T::borrow_from_payload(&payload)) } + } else { + None + } + } + pub fn get_mut(&mut self, index: usize) -> ManagedVecRefMut { ManagedVecRefMut::new(self.get_handle(), index) } pub(super) unsafe fn get_unsafe(&self, index: usize) -> T { - let byte_index = index * T::payload_size(); let mut payload = T::PAYLOAD::new_buffer(); - if self - .buffer - .load_slice(byte_index, payload.payload_slice_mut()) - .is_err() - { + if self.load_item_payload(index, &mut payload) { + T::read_from_payload(&payload) + } else { M::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_MSG); } - T::read_from_payload(&payload) } pub fn set(&mut self, index: usize, item: T) -> Result<(), InvalidSliceError> { diff --git a/framework/scenario/tests/managed_vec_test.rs b/framework/scenario/tests/managed_vec_test.rs index b11fe76788..86dfc76802 100644 --- a/framework/scenario/tests/managed_vec_test.rs +++ b/framework/scenario/tests/managed_vec_test.rs @@ -1,6 +1,6 @@ use std::ops::Deref; -use multiversx_sc::types::{BigUint, ManagedVec}; +use multiversx_sc::types::{BigUint, ManagedRef, ManagedVec}; use multiversx_sc_scenario::api::StaticApi; #[test] @@ -595,3 +595,18 @@ fn test_managed_vec_get_mut() { assert_eq!(*managed_vec.get(0), 200u32); assert_eq!(*managed_vec.get(1), 300u32); } + +#[test] +fn test_is_single_item() { + let mut managed_vec = ManagedVec::>::new(); + assert!(managed_vec.is_single_item().is_none()); + + managed_vec.push(BigUint::::from(1u32)); + assert_eq!( + managed_vec.is_single_item(), + Some(ManagedRef::new(&BigUint::::from(1u32))) + ); + + managed_vec.push(BigUint::::from(2u32)); + assert!(managed_vec.is_single_item().is_none()); +} From 29914f5895b1d2812ce419c3b1e7686c38874a3b Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 1 Jan 2025 16:57:11 +0200 Subject: [PATCH 114/133] EgldOrEsdtTokenPaymentMultiValue --- .../{multi_value/mod.rs => multi_value.rs} | 2 + .../egld_or_esdt_token_payment_multi_value.rs | 113 ++++++++++++++++++ .../esdt_token_payment_multi_value.rs | 2 +- .../wrapped/egld_or_esdt_token_payment.rs | 13 +- .../src/preprocessing/substitution_list.rs | 1 + 5 files changed, 129 insertions(+), 2 deletions(-) rename framework/base/src/types/managed/{multi_value/mod.rs => multi_value.rs} (87%) create mode 100644 framework/base/src/types/managed/multi_value/egld_or_esdt_token_payment_multi_value.rs diff --git a/framework/base/src/types/managed/multi_value/mod.rs b/framework/base/src/types/managed/multi_value.rs similarity index 87% rename from framework/base/src/types/managed/multi_value/mod.rs rename to framework/base/src/types/managed/multi_value.rs index bfd2981c16..29920ed566 100644 --- a/framework/base/src/types/managed/multi_value/mod.rs +++ b/framework/base/src/types/managed/multi_value.rs @@ -1,4 +1,5 @@ mod async_call_result_managed; +mod egld_or_esdt_token_payment_multi_value; mod esdt_token_payment_multi_value; mod multi_value_encoded; mod multi_value_encoded_counted; @@ -7,6 +8,7 @@ mod multi_value_managed_vec; mod multi_value_managed_vec_counted; pub use async_call_result_managed::{ManagedAsyncCallError, ManagedAsyncCallResult}; +pub use egld_or_esdt_token_payment_multi_value::EgldOrEsdtTokenPaymentMultiValue; pub use esdt_token_payment_multi_value::{EsdtTokenPaymentMultiArg, EsdtTokenPaymentMultiValue}; pub use multi_value_encoded::{ManagedMultiResultVec, ManagedVarArgs, MultiValueEncoded}; pub use multi_value_encoded_counted::MultiValueEncodedCounted; diff --git a/framework/base/src/types/managed/multi_value/egld_or_esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/egld_or_esdt_token_payment_multi_value.rs new file mode 100644 index 0000000000..e9f4079b96 --- /dev/null +++ b/framework/base/src/types/managed/multi_value/egld_or_esdt_token_payment_multi_value.rs @@ -0,0 +1,113 @@ +use crate::{ + abi::TypeAbiFrom, + codec::{ + multi_types::MultiValue3, DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, + TopDecodeMultiInput, TopDecodeMultiLength, TopEncodeMulti, TopEncodeMultiOutput, + }, + types::{EgldOrEsdtTokenIdentifier, ManagedVecRef}, +}; + +use crate::{ + abi::{TypeAbi, TypeName}, + api::ManagedTypeApi, + types::{BigUint, EgldOrEsdtTokenPayment, ManagedVecItem, TokenIdentifier}, +}; + +/// Thin wrapper around EgldOrEsdtTokenPayment, which has different I/O behaviour: +/// - as input, is built from 3 arguments instead of 1: token identifier, nonce, value +/// - as output, it becomes 3 results instead of 1: token identifier, nonce, value +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct EgldOrEsdtTokenPaymentMultiValue { + obj: EgldOrEsdtTokenPayment, +} + +impl From> for EgldOrEsdtTokenPaymentMultiValue { + #[inline] + fn from(obj: EgldOrEsdtTokenPayment) -> Self { + EgldOrEsdtTokenPaymentMultiValue { obj } + } +} + +impl EgldOrEsdtTokenPaymentMultiValue { + pub fn into_inner(self) -> EgldOrEsdtTokenPayment { + self.obj + } +} + +impl ManagedVecItem for EgldOrEsdtTokenPaymentMultiValue { + type PAYLOAD = as ManagedVecItem>::PAYLOAD; + const SKIPS_RESERIALIZATION: bool = EgldOrEsdtTokenPayment::::SKIPS_RESERIALIZATION; + type Ref<'a> = ManagedVecRef<'a, Self>; + + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + EgldOrEsdtTokenPayment::read_from_payload(payload).into() + } + + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + ManagedVecRef::new(Self::read_from_payload(payload)) + } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.obj.save_to_payload(payload); + } +} + +impl TopEncodeMulti for EgldOrEsdtTokenPaymentMultiValue +where + M: ManagedTypeApi, +{ + fn multi_encode_or_handle_err(&self, output: &mut O, h: H) -> Result<(), H::HandledErr> + where + O: TopEncodeMultiOutput, + H: EncodeErrorHandler, + { + output.push_single_value(&self.obj.token_identifier, h)?; + output.push_single_value(&self.obj.token_nonce, h)?; + output.push_single_value(&self.obj.amount, h)?; + Ok(()) + } +} + +impl TopDecodeMulti for EgldOrEsdtTokenPaymentMultiValue +where + M: ManagedTypeApi, +{ + fn multi_decode_or_handle_err(input: &mut I, h: H) -> Result + where + I: TopDecodeMultiInput, + H: DecodeErrorHandler, + { + let token_identifier = EgldOrEsdtTokenIdentifier::multi_decode_or_handle_err(input, h)?; + let token_nonce = u64::multi_decode_or_handle_err(input, h)?; + let amount = BigUint::multi_decode_or_handle_err(input, h)?; + Ok(EgldOrEsdtTokenPayment::new(token_identifier, token_nonce, amount).into()) + } +} + +impl TopDecodeMultiLength for EgldOrEsdtTokenPaymentMultiValue +where + M: ManagedTypeApi, +{ + const LEN: usize = 3; +} + +impl TypeAbiFrom for EgldOrEsdtTokenPaymentMultiValue where M: ManagedTypeApi {} + +impl TypeAbi for EgldOrEsdtTokenPaymentMultiValue +where + M: ManagedTypeApi, +{ + type Unmanaged = Self; + + fn type_name() -> TypeName { + MultiValue3::, u64, BigUint>::type_name() + } + + fn type_name_rust() -> TypeName { + "EgldOrEsdtTokenPaymentMultiValue<$API>".into() + } + + fn is_variadic() -> bool { + true + } +} diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index e97cc2707c..34fb1ecacf 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -35,7 +35,7 @@ impl From> for EsdtTokenPaymentMultiValue } impl EsdtTokenPaymentMultiValue { - pub fn into_esdt_token_payment(self) -> EsdtTokenPayment { + pub fn into_inner(self) -> EsdtTokenPayment { self.obj } } diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs index f8d9fa18e0..6ef608c0a9 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs @@ -1,7 +1,9 @@ +use multiversx_sc_codec::IntoMultiValue; + use crate::{ abi::TypeAbiFrom, api::ManagedTypeApi, - types::{BigUint, EgldOrEsdtTokenIdentifier}, + types::{BigUint, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPaymentMultiValue}, }; use crate::codec::{ @@ -133,6 +135,15 @@ impl From> for EgldOrEsdtTokenPayment } } +impl IntoMultiValue for EgldOrEsdtTokenPayment { + type MultiValue = EgldOrEsdtTokenPaymentMultiValue; + + #[inline] + fn into_multi_value(self) -> Self::MultiValue { + self.into() + } +} + impl TypeAbiFrom<&[u8]> for EgldOrEsdtTokenPayment where M: ManagedTypeApi {} impl EgldOrEsdtTokenPayment { diff --git a/framework/derive/src/preprocessing/substitution_list.rs b/framework/derive/src/preprocessing/substitution_list.rs index c03bd3b29e..6f04b19d5f 100644 --- a/framework/derive/src/preprocessing/substitution_list.rs +++ b/framework/derive/src/preprocessing/substitution_list.rs @@ -56,6 +56,7 @@ fn add_managed_types(substitutions: &mut SubstitutionsMap) { add_managed_type_with_generics(substitutions, "e!(ManagedAsyncCallResult)); add_managed_type(substitutions, "e!(EsdtTokenPaymentMultiArg)); add_managed_type(substitutions, "e!(EsdtTokenPaymentMultiValue)); + add_managed_type(substitutions, "e!(EgldOrEsdtTokenPaymentMultiValue)); add_managed_type_with_generics(substitutions, "e!(MultiValueEncodedIterator)); add_managed_type_with_generics(substitutions, "e!(MultiValueEncoded)); add_managed_type_with_generics(substitutions, "e!(ManagedVarArgs)); From 7c83110e12e56275b3d32350df1569f561d7e1b8 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 1 Jan 2025 17:06:05 +0200 Subject: [PATCH 115/133] unified syntax - transfer-exec EGLD fix --- .../forwarder/src/fwd_call_transf_exec.rs | 4 +- .../src/fwd_call_promise_direct.rs | 2 +- ..._exec_accept_multi_transfer_egld.scen.json | 300 ++++++++++++++++++ .../wrappers/send_raw_wrapper.rs | 32 +- .../tx_payment_multi_egld_or_esdt.rs | 17 +- 5 files changed, 340 insertions(+), 15 deletions(-) create mode 100644 contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer_egld.scen.json 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 952f50275c..f040dbce83 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 @@ -95,13 +95,13 @@ pub trait ForwarderTransferExecuteModule { fn transf_exec_multi_accept_funds( &self, to: ManagedAddress, - token_payments: MultiValueEncoded>, + token_payments: MultiValueEncoded>, ) { let mut all_token_payments = ManagedVec::new(); for multi_arg in token_payments.into_iter() { let (token_identifier, token_nonce, amount) = multi_arg.into_tuple(); - let payment = EsdtTokenPayment::new(token_identifier, token_nonce, amount); + let payment = EgldOrEsdtTokenPayment::new(token_identifier, token_nonce, amount); all_token_payments.push(payment); } diff --git a/contracts/feature-tests/composability/promises-features/src/fwd_call_promise_direct.rs b/contracts/feature-tests/composability/promises-features/src/fwd_call_promise_direct.rs index 78635d26b6..67f12798fb 100644 --- a/contracts/feature-tests/composability/promises-features/src/fwd_call_promise_direct.rs +++ b/contracts/feature-tests/composability/promises-features/src/fwd_call_promise_direct.rs @@ -35,7 +35,7 @@ pub trait CallPromisesDirectModule { ) { let mut token_payments_vec = ManagedVec::new(); for token_payment_arg in token_payment_args { - token_payments_vec.push(token_payment_arg.into_esdt_token_payment()); + token_payments_vec.push(token_payment_arg.into_inner()); } let gas_limit = (self.blockchain().get_gas_left() - extra_gas_for_callback) * 9 / 10; diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer_egld.scen.json new file mode 100644 index 0000000000..0f8a4c7c24 --- /dev/null +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer_egld.scen.json @@ -0,0 +1,300 @@ +{ + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "address:a_user": { + "nonce": "0", + "balance": "0" + }, + "sc:forwarder": { + "nonce": "0", + "balance": "100000", + "esdt": { + "str:FWD-TOKEN": "1000", + "str:NFT-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1" + } + ] + }, + "str:SFT-456789": { + "instances": [ + { + "nonce": "3", + "balance": "10" + } + ] + } + }, + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" + }, + "sc:vault": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../vault/output/vault.mxsc.json" + } + } + }, + { + "step": "scCall", + "id": "forward egld x 1", + "tx": { + "from": "address:a_user", + "to": "sc:forwarder", + "function": "transf_exec_multi_accept_funds", + "arguments": [ + "sc:vault", + "str:EGLD", + "0", + "1000" + ], + "gasLimit": "1,400,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "0", + "message": "", + "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "1000", + "sc:vault" + ], + "data": [ + "str:TransferAndExecute", + "str:accept_funds" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:accept_funds", + "topics": [ + "str:accept_funds", + "1000" + ], + "data": [ + "" + ] + } + ] + } + }, + { + "step": "scCall", + "id": "forward egld x 2", + "comment": "send fungible twice", + "tx": { + "from": "address:a_user", + "to": "sc:forwarder", + "function": "transf_exec_multi_accept_funds", + "arguments": [ + "sc:vault", + "str:EGLD", + "0", + "1000", + "str:EGLD", + "0", + "2000" + ], + "gasLimit": "1,400,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "0", + "message": "", + "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:MultiESDTNFTTransfer", + "topics": [ + "str:EGLD-000000", + "0", + "1000", + "str:EGLD-000000", + "0", + "2000", + "sc:vault" + ], + "data": [ + "str:TransferAndExecute", + "str:MultiESDTNFTTransfer", + "sc:vault", + "2", + "str:EGLD-000000", + "0", + "1000", + "str:EGLD-000000", + "0", + "2000", + "str:accept_funds" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:accept_funds", + "topics": [ + "str:accept_funds", + "0", + "str:EGLD", + "0", + "1000", + "str:EGLD", + "0", + "2000" + ], + "data": [ + "" + ] + } + ] + } + }, + { + "step": "checkState", + "accounts": { + "address:a_user": { + "nonce": "*", + "balance": "0", + "storage": {}, + "code": "" + }, + "sc:vault": { + "nonce": "0", + "balance": "4000", + "storage": { + "str:call_counts|nested:str:accept_funds": "2" + }, + "code": "mxsc:../vault/output/vault.mxsc.json" + }, + "sc:forwarder": { + "nonce": "0", + "balance": "96000", + "esdt": { + "str:FWD-TOKEN": "1000", + "str:NFT-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1" + } + ] + }, + "str:SFT-456789": { + "instances": [ + { + "nonce": "3", + "balance": "10" + } + ] + } + }, + "storage": {}, + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" + } + } + }, + { + "step": "scCall", + "id": "1", + "comment": "send EGLD+ESDT", + "tx": { + "from": "address:a_user", + "to": "sc:forwarder", + "function": "transf_exec_multi_accept_funds", + "arguments": [ + "sc:vault", + "str:FWD-TOKEN", + "0", + "500", + "str:FWD-TOKEN", + "0", + "300", + "str:EGLD", + "0", + "3200", + "str:NFT-123456", + "1", + "1", + "str:SFT-456789", + "3", + "6", + "str:EGLD", + "0", + "3300" + ], + "gasLimit": "1,400,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "0", + "message": "", + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "address:a_user": { + "nonce": "*", + "balance": "0", + "storage": {}, + "code": "" + }, + "sc:vault": { + "nonce": "0", + "balance": "10500", + "esdt": { + "str:FWD-TOKEN": "800", + "str:NFT-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1" + } + ] + }, + "str:SFT-456789": { + "instances": [ + { + "nonce": "3", + "balance": "6" + } + ] + } + }, + "storage": { + "str:call_counts|nested:str:accept_funds": "3" + }, + "code": "mxsc:../vault/output/vault.mxsc.json" + }, + "sc:forwarder": { + "nonce": "0", + "balance": "89500", + "esdt": { + "str:FWD-TOKEN": "200", + "str:SFT-456789": { + "instances": [ + { + "nonce": "3", + "balance": "4" + } + ] + } + }, + "storage": {}, + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" + } + } + } + ] +} diff --git a/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs b/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs index 07466ac234..f3d22f8842 100644 --- a/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs @@ -6,8 +6,8 @@ use crate::{ HandleConstraints, ManagedBufferApiImpl, RawHandle, SendApiImpl, StaticVarApiImpl, }, types::{ - BigUint, CodeMetadata, EsdtTokenPayment, ManagedAddress, ManagedArgBuffer, ManagedBuffer, - ManagedType, ManagedVec, TokenIdentifier, + BigUint, CodeMetadata, EgldOrEsdtTokenPayment, EsdtTokenPayment, ManagedAddress, + ManagedArgBuffer, ManagedBuffer, ManagedType, ManagedVec, TokenIdentifier, }, }; @@ -124,6 +124,34 @@ where ) } + pub fn multi_egld_or_esdt_transfer_execute( + &self, + to: &ManagedAddress, + payments: &ManagedVec>, + gas_limit: u64, + endpoint_name: &ManagedBuffer, + arg_buffer: &ManagedArgBuffer, + ) -> Result<(), &'static [u8]> { + if let Some(single_item) = payments.is_single_item() { + if single_item.token_identifier.is_egld() { + return self.direct_egld_execute( + to, + &single_item.amount, + gas_limit, + endpoint_name, + arg_buffer, + ); + } + } + A::send_api_impl().multi_transfer_esdt_nft_execute( + to.get_handle().get_raw_handle(), + payments.get_handle().get_raw_handle(), + gas_limit, + endpoint_name.get_handle().get_raw_handle(), + arg_buffer.get_handle().get_raw_handle(), + ) + } + pub fn async_call_raw( &self, to: &ManagedAddress, diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_multi_egld_or_esdt.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_multi_egld_or_esdt.rs index 149a052cea..4ee31b83e9 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_multi_egld_or_esdt.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_multi_egld_or_esdt.rs @@ -1,11 +1,8 @@ use core::ops::Deref; use crate::{ - api::{HandleConstraints, SendApi, SendApiImpl}, - types::{ - BigUint, ManagedAddress, ManagedRef, ManagedType, MultiEgldOrEsdtPayment, TxFrom, - TxToSpecified, - }, + contract_base::SendRawWrapper, + types::{BigUint, ManagedAddress, ManagedRef, MultiEgldOrEsdtPayment, TxFrom, TxToSpecified}, }; use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; @@ -25,12 +22,12 @@ where gas_limit: u64, fc: FunctionCall, ) { - let _ = Env::Api::send_api_impl().multi_transfer_esdt_nft_execute( - to.get_handle().get_raw_handle(), - self.get_handle().get_raw_handle(), + let _ = SendRawWrapper::::new().multi_egld_or_esdt_transfer_execute( + to, + self, gas_limit, - fc.function_name.get_handle().get_raw_handle(), - fc.arg_buffer.get_handle().get_raw_handle(), + &fc.function_name, + &fc.arg_buffer, ); } From e066bc0ca0a3edb66a45778d853b83c41b3f4c03 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 3 Jan 2025 11:25:34 +0200 Subject: [PATCH 116/133] unified syntax - normalize EGLD multi-transfer fix --- .../forwarder/src/fwd_call_async.rs | 4 +- ...r_call_async_multi_transfer_egld.scen.json | 80 +------------------ .../tests/composability_scenario_go_test.rs | 10 +++ .../tests/composability_scenario_rs_test.rs | 10 +++ .../composability/vault/src/vault.rs | 16 ++-- .../wrappers/call_value_wrapper.rs | 10 +++ .../interaction/tx_data/function_call.rs | 11 ++- 7 files changed, 50 insertions(+), 91 deletions(-) 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 5492a45a10..047eb8f0ee 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_call_async.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_async.rs @@ -177,13 +177,13 @@ pub trait ForwarderAsyncCallModule { fn send_async_accept_multi_transfer( &self, to: ManagedAddress, - token_payments: MultiValueEncoded>, + token_payments: MultiValueEncoded>, ) { let mut all_token_payments = ManagedVec::new(); for multi_arg in token_payments.into_iter() { let (token_identifier, token_nonce, amount) = multi_arg.into_tuple(); - let payment = EsdtTokenPayment::new(token_identifier, token_nonce, amount); + let payment = EgldOrEsdtTokenPayment::new(token_identifier, token_nonce, amount); all_token_payments.push(payment); } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer_egld.scen.json index 7dc86ee64f..50c842422e 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer_egld.scen.json @@ -1,5 +1,4 @@ { - "gasSchedule": "v3", "steps": [ { "step": "setState", @@ -39,81 +38,6 @@ } } }, - { - "step": "scCall", - "id": "1", - "comment": "send fungible twice", - "tx": { - "from": "address:a_user", - "to": "sc:forwarder", - "function": "send_async_accept_multi_transfer", - "arguments": [ - "sc:vault", - "str:FWD-TOKEN", - "0", - "100", - "str:FWD-TOKEN", - "0", - "200" - ], - "gasLimit": "80,000,000", - "gasPrice": "0" - }, - "expect": { - "out": [], - "status": "0", - "message": "", - "gas": "*", - "refund": "*" - } - }, - { - "step": "checkState", - "accounts": { - "address:a_user": { - "nonce": "*", - "balance": "0", - "storage": {}, - "code": "" - }, - "sc:vault": { - "nonce": "0", - "balance": "0", - "esdt": { - "str:FWD-TOKEN": "300" - }, - "storage": { - "str:call_counts|nested:str:accept_funds": "1" - }, - "code": "mxsc:../vault/output/vault.mxsc.json" - }, - "sc:forwarder": { - "nonce": "0", - "balance": "4000", - "esdt": { - "str:FWD-TOKEN": "700", - "str:NFT-123456": { - "instances": [ - { - "nonce": "1", - "balance": "1" - } - ] - }, - "str:SFT-456789": { - "instances": [ - { - "nonce": "3", - "balance": "10" - } - ] - } - }, - "storage": {}, - "code": "mxsc:../forwarder/output/forwarder.mxsc.json" - } - } - }, { "step": "scCall", "id": "2", @@ -126,7 +50,7 @@ "sc:vault", "str:FWD-TOKEN", "0", - "500", + "800", "str:NFT-123456", "1", "1", @@ -180,7 +104,7 @@ } }, "storage": { - "str:call_counts|nested:str:accept_funds": "2" + "str:call_counts|nested:str:accept_funds": "1" }, "code": "mxsc:../vault/output/vault.mxsc.json" }, diff --git a/contracts/feature-tests/composability/tests/composability_scenario_go_test.rs b/contracts/feature-tests/composability/tests/composability_scenario_go_test.rs index 3dfb9fdc2d..eec670604c 100644 --- a/contracts/feature-tests/composability/tests/composability_scenario_go_test.rs +++ b/contracts/feature-tests/composability/tests/composability_scenario_go_test.rs @@ -184,6 +184,11 @@ fn forwarder_call_async_multi_transfer_go() { world().run("scenarios/forwarder_call_async_multi_transfer.scen.json"); } +#[test] +fn forwarder_call_async_multi_transfer_egld_go() { + world().run("scenarios/forwarder_call_async_multi_transfer_egld.scen.json"); +} + #[test] fn forwarder_call_async_retrieve_egld_go() { world().run("scenarios/forwarder_call_async_retrieve_egld.scen.json"); @@ -289,6 +294,11 @@ fn forwarder_call_transf_exec_accept_multi_transfer_go() { world().run("scenarios/forwarder_call_transf_exec_accept_multi_transfer.scen.json"); } +#[test] +fn forwarder_call_transf_exec_accept_multi_transfer_egld_go() { + world().run("scenarios/forwarder_call_transf_exec_accept_multi_transfer_egld.scen.json"); +} + #[test] fn forwarder_call_transf_exec_accept_nft_go() { world().run("scenarios/forwarder_call_transf_exec_accept_nft.scen.json"); diff --git a/contracts/feature-tests/composability/tests/composability_scenario_rs_test.rs b/contracts/feature-tests/composability/tests/composability_scenario_rs_test.rs index dce2f9031a..94fc855cf9 100644 --- a/contracts/feature-tests/composability/tests/composability_scenario_rs_test.rs +++ b/contracts/feature-tests/composability/tests/composability_scenario_rs_test.rs @@ -238,6 +238,11 @@ fn forwarder_call_async_multi_transfer_rs() { world().run("scenarios/forwarder_call_async_multi_transfer.scen.json"); } +#[test] +fn forwarder_call_async_multi_transfer_egld_rs() { + world().run("scenarios/forwarder_call_async_multi_transfer_egld.scen.json"); +} + #[test] fn forwarder_call_async_retrieve_egld_rs() { world().run("scenarios/forwarder_call_async_retrieve_egld.scen.json"); @@ -343,6 +348,11 @@ fn forwarder_call_transf_exec_accept_multi_transfer_rs() { world().run("scenarios/forwarder_call_transf_exec_accept_multi_transfer.scen.json"); } +#[test] +fn forwarder_call_transf_exec_accept_multi_transfer_egld_rs() { + world().run("scenarios/forwarder_call_transf_exec_accept_multi_transfer_egld.scen.json"); +} + #[test] fn forwarder_call_transf_exec_accept_nft_rs() { world().run("scenarios/forwarder_call_transf_exec_accept_nft.scen.json"); diff --git a/contracts/feature-tests/composability/vault/src/vault.rs b/contracts/feature-tests/composability/vault/src/vault.rs index d6f3feb81b..e700ebda36 100644 --- a/contracts/feature-tests/composability/vault/src/vault.rs +++ b/contracts/feature-tests/composability/vault/src/vault.rs @@ -50,9 +50,9 @@ pub trait Vault { self.blockchain().get_caller() } - fn esdt_transfers_multi(&self) -> MultiValueEncoded { + fn all_transfers_multi(&self) -> MultiValueEncoded { self.call_value() - .all_esdt_transfers() + .all_multi_transfers() .clone_value() .into_multi_value() } @@ -60,7 +60,7 @@ pub trait Vault { #[payable("*")] #[endpoint] fn accept_funds(&self) { - let esdt_transfers_multi = self.esdt_transfers_multi(); + let esdt_transfers_multi = self.all_transfers_multi(); self.accept_funds_event(&self.call_value().egld_value(), &esdt_transfers_multi); self.call_counts(ManagedBuffer::from(b"accept_funds")) @@ -71,9 +71,9 @@ pub trait Vault { #[endpoint] fn accept_funds_echo_payment( &self, - ) -> MultiValue2> { + ) -> MultiValue2> { let egld_value = self.call_value().egld_value(); - let esdt_transfers_multi = self.esdt_transfers_multi(); + let esdt_transfers_multi = self.all_transfers_multi(); self.accept_funds_event(&egld_value, &esdt_transfers_multi); self.call_counts(ManagedBuffer::from(b"accept_funds_echo_payment")) @@ -91,7 +91,7 @@ pub trait Vault { #[payable("*")] #[endpoint] fn reject_funds(&self) { - let esdt_transfers_multi = self.esdt_transfers_multi(); + let esdt_transfers_multi = self.all_transfers_multi(); self.reject_funds_event(&self.call_value().egld_value(), &esdt_transfers_multi); sc_panic!("reject_funds"); } @@ -259,14 +259,14 @@ pub trait Vault { fn accept_funds_event( &self, #[indexed] egld_value: &BigUint, - #[indexed] multi_esdt: &MultiValueEncoded, + #[indexed] multi_esdt: &MultiValueEncoded, ); #[event("reject_funds")] fn reject_funds_event( &self, #[indexed] egld_value: &BigUint, - #[indexed] multi_esdt: &MultiValueEncoded, + #[indexed] multi_esdt: &MultiValueEncoded, ); #[event("retrieve_funds")] diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index dea8246d00..43f798acbc 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -165,6 +165,16 @@ where unsafe { ManagedRef::wrap_handle(all_transfers_handle) } } + /// Same as `all_transfers`, but without EGLD singleton. + /// + /// Temporary! + pub fn all_multi_transfers( + &self, + ) -> ManagedRef<'static, A, ManagedVec>> { + let all_transfers_unchecked_handle = self.all_esdt_transfers_unchecked(); + unsafe { ManagedRef::wrap_handle(all_transfers_unchecked_handle) } + } + /// Verify and casts the received multi ESDT transfer in to an array. /// /// Can be used to extract all payments in one line like this: diff --git a/framework/base/src/types/interaction/tx_data/function_call.rs b/framework/base/src/types/interaction/tx_data/function_call.rs index 1972e009f7..2d359a04e6 100644 --- a/framework/base/src/types/interaction/tx_data/function_call.rs +++ b/framework/base/src/types/interaction/tx_data/function_call.rs @@ -166,8 +166,10 @@ where self, payment: EsdtTokenPaymentRefs<'_, Api>, ) -> FunctionCall { + // EGLD not supported + // but serializing token identifier buffer for efficiency, no need to convert to "EGLD" from "EGLD-000000" FunctionCall::new(ESDT_TRANSFER_FUNC_NAME) - .argument(&payment.token_identifier) + .argument(&payment.token_identifier.as_managed_buffer()) .argument(&payment.amount) .argument(&self) } @@ -184,8 +186,10 @@ where to: &ManagedAddress, payment: EsdtTokenPaymentRefs<'_, Api>, ) -> FunctionCall { + // EGLD not supported + // but serializing token identifier buffer for efficiency, no need to convert to "EGLD" from "EGLD-000000" FunctionCall::new(ESDT_NFT_TRANSFER_FUNC_NAME) - .argument(&payment.token_identifier) + .argument(&payment.token_identifier.as_managed_buffer()) .argument(&payment.token_nonce) .argument(&payment.amount) .argument(to) @@ -203,8 +207,9 @@ where .argument(&payments.len()); for payment in payments { + // serializing token identifier buffer to get EGLD-00000 instead of EGLD result = result - .argument(&payment.token_identifier) + .argument(&payment.token_identifier.buffer) .argument(&payment.token_nonce) .argument(&payment.amount); } From 8a44fa1d9c6f86628373b1f315a40174701555b0 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sat, 4 Jan 2025 19:47:44 +0200 Subject: [PATCH 117/133] token identifier rejects EGLD --- .../scenarios/echo_managed_vec.scen.json | 50 ++++++++++++++++++- framework/base/src/err_msg.rs | 3 +- .../wrapped/egld_or_esdt_token_identifier.rs | 5 +- .../types/managed/wrapped/token_identifier.rs | 26 +++++++--- 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/contracts/feature-tests/basic-features/scenarios/echo_managed_vec.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_managed_vec.scen.json index aca55e1466..f3cbd54b4d 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_managed_vec.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_managed_vec.scen.json @@ -97,7 +97,6 @@ "arguments": [ [ "nested:str:TOKENA-1234", - "nested:str:EGLD", "nested:str:TOKENB-1234" ] ], @@ -108,7 +107,6 @@ "out": [ [ "nested:str:TOKENA-1234", - "nested:str:EGLD", "nested:str:TOKENB-1234" ] ], @@ -117,6 +115,54 @@ "gas": "*", "refund": "*" } + }, + { + "step": "scCall", + "id": "echo_managed_vec_of_token_identifier-EGLD", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "echo_managed_vec_of_token_identifier", + "arguments": [ + [ + "nested:str:EGLD" + ] + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:argument decode error (mv): ESDT expected", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "echo_managed_vec_of_token_identifier-EGLD-000000", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "echo_managed_vec_of_token_identifier", + "arguments": [ + [ + "nested:str:EGLD-000000" + ] + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:argument decode error (mv): ESDT expected", + "logs": "*", + "gas": "*", + "refund": "*" + } } ] } diff --git a/framework/base/src/err_msg.rs b/framework/base/src/err_msg.rs index 5067013c77..019a0c325e 100644 --- a/framework/base/src/err_msg.rs +++ b/framework/base/src/err_msg.rs @@ -9,7 +9,8 @@ pub const TOO_MANY_ESDT_TRANSFERS: &str = "too many ESDT transfers"; pub const ESDT_INVALID_TOKEN_INDEX: &str = "invalid token index"; pub const ESDT_UNEXPECTED_EGLD: &str = "unexpected EGLD transfer"; pub const INCORRECT_NUM_ESDT_TRANSFERS: &str = "incorrect number of ESDT transfers"; -pub static FUNGIBLE_TOKEN_EXPECTED_ERR_MSG: &str = "fungible ESDT token expected"; +pub const FUNGIBLE_TOKEN_EXPECTED_ERR_MSG: &str = "fungible ESDT token expected"; +pub const TOKEN_IDENTIFIER_ESDT_EXPECTED: &str = "ESDT expected"; pub const ARG_WRONG_NUMBER: &str = "wrong number of arguments"; pub const ARG_ASYNC_WRONG_NUMBER: &str = "wrong number of arguments provided to async call"; diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index a2f14f6063..827e269002 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -8,6 +8,7 @@ use crate::{ ManagedTypeApi, }, codec::*, + err_msg, formatter::{FormatByteReceiver, SCDisplay, SCLowerHex}, proxy_imports::TestTokenIdentifier, types::{ManagedBuffer, ManagedRef, ManagedType, TokenIdentifier}, @@ -174,7 +175,9 @@ impl EgldOrEsdtTokenIdentifier { pub fn unwrap_esdt(self) -> TokenIdentifier { self.map_or_else( (), - |()| M::error_api_impl().signal_error(b"ESDT expected"), + |()| { + M::error_api_impl().signal_error(err_msg::TOKEN_IDENTIFIER_ESDT_EXPECTED.as_bytes()) + }, |(), token_identifier| token_identifier, ) } diff --git a/framework/base/src/types/managed/wrapped/token_identifier.rs b/framework/base/src/types/managed/wrapped/token_identifier.rs index 6228fba515..6bf65bfd02 100644 --- a/framework/base/src/types/managed/wrapped/token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/token_identifier.rs @@ -59,6 +59,14 @@ impl TokenIdentifier { Self { data } } + pub fn try_new(data: EgldOrEsdtTokenIdentifier) -> Option { + if data.is_egld() { + return None; + } + + unsafe { Some(Self::esdt_unchecked(data)) } + } + #[inline] pub fn from_esdt_bytes>>(bytes: B) -> Self { TokenIdentifier::from(bytes.into()) @@ -166,10 +174,11 @@ impl NestedDecode for TokenIdentifier { I: NestedDecodeInput, H: DecodeErrorHandler, { - unsafe { - Ok(TokenIdentifier::esdt_unchecked( - EgldOrEsdtTokenIdentifier::dep_decode_or_handle_err(input, h)?, - )) + let data = EgldOrEsdtTokenIdentifier::dep_decode_or_handle_err(input, h)?; + if let Some(ti) = TokenIdentifier::try_new(data) { + Ok(ti) + } else { + Err(h.handle_error(err_msg::TOKEN_IDENTIFIER_ESDT_EXPECTED.into())) } } } @@ -180,10 +189,11 @@ impl TopDecode for TokenIdentifier { I: TopDecodeInput, H: DecodeErrorHandler, { - unsafe { - Ok(TokenIdentifier::esdt_unchecked( - EgldOrEsdtTokenIdentifier::top_decode_or_handle_err(input, h)?, - )) + let data = EgldOrEsdtTokenIdentifier::top_decode_or_handle_err(input, h)?; + if let Some(ti) = TokenIdentifier::try_new(data) { + Ok(ti) + } else { + Err(h.handle_error(err_msg::TOKEN_IDENTIFIER_ESDT_EXPECTED.into())) } } } From 453dc2b710342762bf3d7486928b7671588969ca Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sat, 4 Jan 2025 19:50:03 +0200 Subject: [PATCH 118/133] cargo update --- Cargo.lock | 51 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa83aca684..f4732ca717 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -376,9 +376,9 @@ checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" [[package]] name = "bstr" -version = "1.11.1" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" dependencies = [ "memchr", "serde", @@ -420,9 +420,9 @@ checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cc" -version = "1.2.5" +version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ "shlex", ] @@ -3448,9 +3448,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.9" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" +checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" dependencies = [ "base64", "bytes", @@ -3486,6 +3486,7 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls", + "tower", "tower-service", "url", "wasm-bindgen", @@ -3662,9 +3663,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "ryu" @@ -3692,9 +3693,9 @@ dependencies = [ [[package]] name = "scc" -version = "2.2.6" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b13f8ea6177672c49d12ed964cca44836f59621981b04a3e26b87e675181de" +checksum = "28e1c91382686d21b5ac7959341fcb9780fa7c03773646995a87c950fa7be640" dependencies = [ "sdd", ] @@ -4164,12 +4165,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand", + "getrandom", "once_cell", "rustix", "windows-sys 0.59.0", @@ -4353,6 +4355,27 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + [[package]] name = "tower-service" version = "0.3.3" @@ -4862,9 +4885,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.20" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" dependencies = [ "memchr", ] From 1db45455fa3f9594dbcc93d19857a0eda98bba07 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sun, 5 Jan 2025 20:20:38 +0200 Subject: [PATCH 119/133] payable-features mandos fix --- .../call-value-check-multi-egld.scen.json | 56 +------------------ .../payable_multi_array_egld.scen.json | 2 +- .../scenarios/payable_multiple_egld.scen.json | 2 +- .../tests/payable_scenario_go_test.rs | 15 +++++ .../tests/payable_scenario_rs_test.rs | 15 +++++ 5 files changed, 34 insertions(+), 56 deletions(-) diff --git a/contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json b/contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json index 8490c055fe..fd8730d1fc 100644 --- a/contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json @@ -26,59 +26,6 @@ } } }, - { - "step": "scCall", - "id": "call-value-egld", - "tx": { - "from": "address:an-account", - "to": "sc:payable-features", - "egldValue": "100", - "function": "echo_call_value", - "arguments": [], - "gasLimit": "50,000,000", - "gasPrice": "0" - }, - "expect": { - "out": [ - "100", - "" - ], - "status": "", - "logs": "*", - "gas": "*", - "refund": "*" - } - }, - { - "step": "scCall", - "id": "call-value-single-esdt", - "tx": { - "from": "address:an-account", - "to": "sc:payable-features", - "esdtValue": [ - { - "tokenIdentifier": "str:TOK-123456", - "value": "100" - } - ], - "function": "echo_call_value", - "arguments": [], - "gasLimit": "50,000,000", - "gasPrice": "0" - }, - "expect": { - "out": [ - "0", - [ - "nested:str:TOK-123456|u64:0|biguint:100" - ] - ], - "status": "", - "logs": "*", - "gas": "*", - "refund": "*" - } - }, { "step": "scCall", "id": "call-value-multi-esdt", @@ -111,8 +58,9 @@ }, "expect": { "out": [ - "15", + "0", [ + "nested:str:EGLD|u64:0|biguint:15", "nested:str:TOK-123456|u64:0|biguint:100", "nested:str:OTHERTOK-123456|u64:0|biguint:400", "nested:str:SFT-123|u64:5|biguint:10" diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json index 16fa1cea20..8daad198aa 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json @@ -133,7 +133,7 @@ "expect": { "out": [ "nested:str:TOK-000001|u64:0|biguint:100", - "nested:str:EGLD-000000|u64:0|biguint:400", + "nested:str:EGLD|u64:0|biguint:400", "nested:str:SFT-123|u64:5|biguint:10" ], "status": "", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json index 28e667b322..3cfc600eab 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json @@ -65,7 +65,7 @@ "nested:str:TOK-123456|u64:0|biguint:100|", "nested:str:OTHERTOK-123456|u64:0|biguint:400", "nested:str:SFT-123|u64:5|biguint:10", - "nested:str:EGLD-000000|u64:0|biguint:120" + "nested:str:EGLD|u64:0|biguint:120" ] ], "status": "", diff --git a/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs b/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs index 95be700ffa..8b9e2a0a80 100644 --- a/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs +++ b/contracts/feature-tests/payable-features/tests/payable_scenario_go_test.rs @@ -9,6 +9,11 @@ fn call_value_check_go() { world().run("scenarios/call-value-check.scen.json"); } +#[test] +fn call_value_check_multi_egld_go() { + world().run("scenarios/call-value-check-multi-egld.scen.json"); +} + #[test] fn payable_all_transfers_go() { world().run("scenarios/payable_all_transfers.scen.json"); @@ -59,11 +64,21 @@ fn payable_multi_array_go() { world().run("scenarios/payable_multi_array.scen.json"); } +#[test] +fn payable_multi_array_egld_go() { + world().run("scenarios/payable_multi_array_egld.scen.json"); +} + #[test] fn payable_multiple_go() { world().run("scenarios/payable_multiple.scen.json"); } +#[test] +fn payable_multiple_egld_go() { + world().run("scenarios/payable_multiple_egld.scen.json"); +} + #[test] fn payable_token_1_go() { world().run("scenarios/payable_token_1.scen.json"); diff --git a/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs b/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs index f3c4f752d9..7928eb3abf 100644 --- a/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs +++ b/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs @@ -15,6 +15,11 @@ fn call_value_check_rs() { world().run("scenarios/call-value-check.scen.json"); } +#[test] +fn call_value_check_multi_egld_rs() { + world().run("scenarios/call-value-check-multi-egld.scen.json"); +} + #[test] fn payable_all_transfers_rs() { world().run("scenarios/payable_all_transfers.scen.json"); @@ -65,11 +70,21 @@ fn payable_multi_array_rs() { world().run("scenarios/payable_multi_array.scen.json"); } +#[test] +fn payable_multi_array_egld_rs() { + world().run("scenarios/payable_multi_array_egld.scen.json"); +} + #[test] fn payable_multiple_rs() { world().run("scenarios/payable_multiple.scen.json"); } +#[test] +fn payable_multiple_egld_rs() { + world().run("scenarios/payable_multiple_egld.scen.json"); +} + #[test] fn payable_token_1_rs() { world().run("scenarios/payable_token_1.scen.json"); From 2aeea32d6e15af7b013c547f15420e10826cd3e2 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Sun, 5 Jan 2025 20:26:11 +0200 Subject: [PATCH 120/133] proxy update --- .../composability/forwarder/src/forwarder_proxy.rs | 4 ++-- .../composability/forwarder/src/fwd_call_sync.rs | 2 +- .../feature-tests/composability/forwarder/src/vault_proxy.rs | 2 +- .../feature-tests/composability/interact/src/vault_proxy.rs | 2 +- .../composability/promises-features/src/vault_proxy.rs | 2 +- .../composability/recursive-caller/src/vault_proxy.rs | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs b/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs index d8ef19f3a4..3020b96543 100644 --- a/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs +++ b/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs @@ -345,7 +345,7 @@ where pub fn send_async_accept_multi_transfer< Arg0: ProxyArg>, - Arg1: ProxyArg, u64, BigUint>>>, + Arg1: ProxyArg, u64, BigUint>>>, >( self, to: Arg0, @@ -445,7 +445,7 @@ where pub fn transf_exec_multi_accept_funds< Arg0: ProxyArg>, - Arg1: ProxyArg, u64, BigUint>>>, + Arg1: ProxyArg, u64, BigUint>>>, >( self, to: Arg0, 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 bb3d86a5d7..1d25c16699 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs @@ -160,7 +160,7 @@ pub trait ForwarderSyncCallModule { fn accept_funds_sync_result_event( &self, #[indexed] egld_value: &BigUint, - #[indexed] multi_esdt: &MultiValueEncoded, + #[indexed] multi_esdt: &MultiValueEncoded, ); #[endpoint] diff --git a/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs b/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs index 9636e1e5d1..8164d1df0e 100644 --- a/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs +++ b/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs @@ -111,7 +111,7 @@ where pub fn accept_funds_echo_payment( self, - ) -> TxTypedCall, MultiValueEncoded>>> { + ) -> TxTypedCall, MultiValueEncoded>>> { self.wrapped_tx .raw_call("accept_funds_echo_payment") .original_result() diff --git a/contracts/feature-tests/composability/interact/src/vault_proxy.rs b/contracts/feature-tests/composability/interact/src/vault_proxy.rs index 9636e1e5d1..8164d1df0e 100644 --- a/contracts/feature-tests/composability/interact/src/vault_proxy.rs +++ b/contracts/feature-tests/composability/interact/src/vault_proxy.rs @@ -111,7 +111,7 @@ where pub fn accept_funds_echo_payment( self, - ) -> TxTypedCall, MultiValueEncoded>>> { + ) -> TxTypedCall, MultiValueEncoded>>> { self.wrapped_tx .raw_call("accept_funds_echo_payment") .original_result() diff --git a/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs b/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs index 9636e1e5d1..8164d1df0e 100644 --- a/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs +++ b/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs @@ -111,7 +111,7 @@ where pub fn accept_funds_echo_payment( self, - ) -> TxTypedCall, MultiValueEncoded>>> { + ) -> TxTypedCall, MultiValueEncoded>>> { self.wrapped_tx .raw_call("accept_funds_echo_payment") .original_result() diff --git a/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs b/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs index 9636e1e5d1..8164d1df0e 100644 --- a/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs +++ b/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs @@ -111,7 +111,7 @@ where pub fn accept_funds_echo_payment( self, - ) -> TxTypedCall, MultiValueEncoded>>> { + ) -> TxTypedCall, MultiValueEncoded>>> { self.wrapped_tx .raw_call("accept_funds_echo_payment") .original_result() From ac5a7cdb675c641c5abed04295bd6a367db86ee5 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 6 Jan 2025 03:43:25 +0200 Subject: [PATCH 121/133] composability tests - vault logs all transfers --- .../composability/forwarder/src/fwd_call_sync.rs | 5 +---- .../composability/forwarder/src/vault_proxy.rs | 2 +- .../composability/interact/src/vault_proxy.rs | 2 +- .../promises-features/src/vault_proxy.rs | 2 +- .../recursive-caller/src/vault_proxy.rs | 2 +- .../scenarios/forw_queue_async.scen.json | 2 ++ .../forw_raw_async_accept_egld.scen.json | 2 ++ .../forw_raw_async_accept_esdt.scen.json | 1 - .../scenarios/forw_raw_sync_egld.scen.json | 6 ++++++ .../forwarder_call_async_accept_egld.scen.json | 2 ++ .../forwarder_call_async_accept_esdt.scen.json | 1 - .../forwarder_call_async_accept_nft.scen.json | 1 - .../forwarder_call_sync_accept_egld.scen.json | 4 ++++ .../forwarder_call_sync_accept_esdt.scen.json | 2 -- ...rder_call_sync_accept_multi_transfer.scen.json | 1 - .../forwarder_call_sync_accept_nft.scen.json | 2 -- ...rder_call_sync_accept_then_read_egld.scen.json | 2 ++ ...rder_call_sync_accept_then_read_esdt.scen.json | 1 - ...arder_call_sync_accept_then_read_nft.scen.json | 1 - ...rwarder_call_transf_exec_accept_egld.scen.json | 2 ++ ...r_call_transf_exec_accept_egld_twice.scen.json | 4 ++++ ...rwarder_call_transf_exec_accept_esdt.scen.json | 1 - ...r_call_transf_exec_accept_esdt_twice.scen.json | 2 -- ...ll_transf_exec_accept_multi_transfer.scen.json | 1 - ...ansf_exec_accept_multi_transfer_egld.scen.json | 3 ++- ...orwarder_call_transf_exec_accept_nft.scen.json | 1 - ...all_transf_exec_accept_return_values.scen.json | 2 ++ ...er_call_transf_exec_accept_sft_twice.scen.json | 2 -- .../promises_call_async_accept_egld.scen.json | 2 ++ .../promises_call_async_accept_esdt.scen.json | 1 - .../scenarios/promises_multi_transfer.scen.json | 4 ---- .../scenarios/recursive_caller_egld_1.scen.json | 2 ++ .../scenarios/recursive_caller_esdt_1.scen.json | 1 - .../composability/vault/src/vault.rs | 15 ++++++--------- .../contract_base/wrappers/call_value_wrapper.rs | 10 ---------- 35 files changed, 43 insertions(+), 51 deletions(-) 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 1d25c16699..d5b6f63492 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs @@ -74,9 +74,7 @@ pub trait ForwarderSyncCallModule { .returns(ReturnsResult) .sync_call(); - let (egld_value, esdt_transfers_multi) = result.into_tuple(); - - self.accept_funds_sync_result_event(&egld_value, &esdt_transfers_multi); + self.accept_funds_sync_result_event(&result); } #[endpoint] @@ -159,7 +157,6 @@ pub trait ForwarderSyncCallModule { #[event("accept_funds_sync_result")] fn accept_funds_sync_result_event( &self, - #[indexed] egld_value: &BigUint, #[indexed] multi_esdt: &MultiValueEncoded, ); diff --git a/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs b/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs index 8164d1df0e..43133e7ca0 100644 --- a/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs +++ b/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs @@ -111,7 +111,7 @@ where pub fn accept_funds_echo_payment( self, - ) -> TxTypedCall, MultiValueEncoded>>> { + ) -> TxTypedCall>> { self.wrapped_tx .raw_call("accept_funds_echo_payment") .original_result() diff --git a/contracts/feature-tests/composability/interact/src/vault_proxy.rs b/contracts/feature-tests/composability/interact/src/vault_proxy.rs index 8164d1df0e..43133e7ca0 100644 --- a/contracts/feature-tests/composability/interact/src/vault_proxy.rs +++ b/contracts/feature-tests/composability/interact/src/vault_proxy.rs @@ -111,7 +111,7 @@ where pub fn accept_funds_echo_payment( self, - ) -> TxTypedCall, MultiValueEncoded>>> { + ) -> TxTypedCall>> { self.wrapped_tx .raw_call("accept_funds_echo_payment") .original_result() diff --git a/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs b/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs index 8164d1df0e..43133e7ca0 100644 --- a/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs +++ b/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs @@ -111,7 +111,7 @@ where pub fn accept_funds_echo_payment( self, - ) -> TxTypedCall, MultiValueEncoded>>> { + ) -> TxTypedCall>> { self.wrapped_tx .raw_call("accept_funds_echo_payment") .original_result() diff --git a/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs b/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs index 8164d1df0e..43133e7ca0 100644 --- a/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs +++ b/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs @@ -111,7 +111,7 @@ where pub fn accept_funds_echo_payment( self, - ) -> TxTypedCall, MultiValueEncoded>>> { + ) -> TxTypedCall>> { self.wrapped_tx .raw_call("accept_funds_echo_payment") .original_result() diff --git a/contracts/feature-tests/composability/scenarios/forw_queue_async.scen.json b/contracts/feature-tests/composability/scenarios/forw_queue_async.scen.json index 87a52541e8..2f48778049 100644 --- a/contracts/feature-tests/composability/scenarios/forw_queue_async.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_queue_async.scen.json @@ -80,6 +80,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "0x03e8" ], "data": "*" diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_egld.scen.json index bcb4567d0e..167faf2bc1 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_egld.scen.json @@ -56,6 +56,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1000" ], "data": [ diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_esdt.scen.json index b6d2e8cb32..77b6b71264 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_esdt.scen.json @@ -69,7 +69,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:TEST-TOKENA", "0", "1000" diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_sync_egld.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_sync_egld.scen.json index fea874bedc..ea20d55338 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_sync_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_sync_egld.scen.json @@ -56,6 +56,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1000" ], "data": [ @@ -113,6 +115,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "500" ], "data": [ @@ -146,6 +150,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "500" ], "data": [ diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_egld.scen.json index 551d98b2e3..1a6e40aa47 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_egld.scen.json @@ -55,6 +55,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1000" ], "data": [ diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_esdt.scen.json index 3420580fea..ba406f0141 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_esdt.scen.json @@ -68,7 +68,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:TEST-TOKENA", "0", "1000" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_nft.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_nft.scen.json index 7ed9909961..84278f1eeb 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_nft.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_nft.scen.json @@ -82,7 +82,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:NFT-000001", "5", "1" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_egld.scen.json index 25f2522e76..2f9d5e2841 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_egld.scen.json @@ -55,6 +55,8 @@ "endpoint": "str:accept_funds_echo_payment", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1000" ], "data": [ @@ -66,6 +68,8 @@ "endpoint": "str:forward_sync_accept_funds", "topics": [ "str:accept_funds_sync_result", + "str:EGLD", + "0", "1000" ], "data": [ diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_esdt.scen.json index fa529ed939..80108eeb28 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_esdt.scen.json @@ -98,7 +98,6 @@ "endpoint": "str:accept_funds_echo_payment", "topics": [ "str:accept_funds", - "0", "str:TEST-TOKENA", "0", "1000" @@ -112,7 +111,6 @@ "endpoint": "str:forward_sync_accept_funds", "topics": [ "str:accept_funds_sync_result", - "0", "str:TEST-TOKENA", "0", "1000" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_multi_transfer.scen.json index 2801ef7051..c1f14998d8 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_multi_transfer.scen.json @@ -122,7 +122,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:FWD-TOKEN", "0", "100", diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_nft.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_nft.scen.json index 716e9540be..aa2f6e5481 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_nft.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_nft.scen.json @@ -82,7 +82,6 @@ "endpoint": "str:accept_funds_echo_payment", "topics": [ "str:accept_funds", - "0", "str:NFT-000001", "5", "1" @@ -96,7 +95,6 @@ "endpoint": "str:forward_sync_accept_funds", "topics": [ "str:accept_funds_sync_result", - "0", "str:NFT-000001", "5", "1" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_egld.scen.json index 284d9fd86d..478d95e20d 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_egld.scen.json @@ -57,6 +57,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1000" ], "data": [ diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_esdt.scen.json index c5453377e4..8b55ff9543 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_esdt.scen.json @@ -70,7 +70,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:TEST-TOKENA", "0", "1000" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_nft.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_nft.scen.json index dde828970f..00415ded09 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_nft.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_nft.scen.json @@ -84,7 +84,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:NFT-000001", "5", "1" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld.scen.json index 0b635d585e..d2da32c423 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld.scen.json @@ -55,6 +55,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1000" ], "data": [ diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld_twice.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld_twice.scen.json index 8c93ba20d8..4998644c84 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld_twice.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld_twice.scen.json @@ -55,6 +55,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1000" ], "data": [ @@ -78,6 +80,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1000" ], "data": [ diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt.scen.json index 8ca18d2175..416f33c59d 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt.scen.json @@ -68,7 +68,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:TEST-TOKENA", "0", "1000" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt_twice.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt_twice.scen.json index cd975b5e41..00921b4a5a 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt_twice.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt_twice.scen.json @@ -68,7 +68,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:TEST-TOKENA", "0", "1000" @@ -99,7 +98,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:TEST-TOKENA", "0", "1000" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer.scen.json index 3902c8306e..9941a0ae0d 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer.scen.json @@ -95,7 +95,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:FWD-TOKEN", "0", "100", diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer_egld.scen.json index 0f8a4c7c24..24e0cc947c 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer_egld.scen.json @@ -77,6 +77,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1000" ], "data": [ @@ -142,7 +144,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:EGLD", "0", "1000", diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_nft.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_nft.scen.json index d3d22a9e91..1336b39c5e 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_nft.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_nft.scen.json @@ -78,7 +78,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:NFT-000001", "5", "1" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_return_values.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_return_values.scen.json index c861c4c39d..8dad5f400a 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_return_values.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_return_values.scen.json @@ -60,6 +60,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1000" ], "data": [ diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_sft_twice.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_sft_twice.scen.json index 1fd4532450..cf8cd4dee6 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_sft_twice.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_sft_twice.scen.json @@ -78,7 +78,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:NFT-000001", "5", "1" @@ -111,7 +110,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:NFT-000001", "5", "1" diff --git a/contracts/feature-tests/composability/scenarios/promises_call_async_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/promises_call_async_accept_egld.scen.json index 6a31fc5068..a9f166c9ca 100644 --- a/contracts/feature-tests/composability/scenarios/promises_call_async_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_call_async_accept_egld.scen.json @@ -54,6 +54,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1000" ], "data": [ diff --git a/contracts/feature-tests/composability/scenarios/promises_call_async_accept_esdt.scen.json b/contracts/feature-tests/composability/scenarios/promises_call_async_accept_esdt.scen.json index c79d953c1d..7a98b311c5 100644 --- a/contracts/feature-tests/composability/scenarios/promises_call_async_accept_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_call_async_accept_esdt.scen.json @@ -67,7 +67,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:TEST-TOKENA", "0", "1000" diff --git a/contracts/feature-tests/composability/scenarios/promises_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/promises_multi_transfer.scen.json index 71eaf90e90..915aba4d9a 100644 --- a/contracts/feature-tests/composability/scenarios/promises_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_multi_transfer.scen.json @@ -64,7 +64,6 @@ }, "expect": { "out": [ - "0", "str:FWD-TOKEN", "0", "500", @@ -115,7 +114,6 @@ "endpoint": "str:accept_funds_echo_payment", "topics": [ "str:accept_funds", - "0", "str:FWD-TOKEN", "0", "500", @@ -141,7 +139,6 @@ "str:AsyncCallback", "str:the_one_callback", "0x00", - "0", "str:FWD-TOKEN", "0", "500", @@ -164,7 +161,6 @@ "data": [ [ "nested:0x00", - "nested:0", "nested:str:FWD-TOKEN", "nested:0", "nested:500", diff --git a/contracts/feature-tests/composability/scenarios/recursive_caller_egld_1.scen.json b/contracts/feature-tests/composability/scenarios/recursive_caller_egld_1.scen.json index 418ee1162b..c72085b89d 100644 --- a/contracts/feature-tests/composability/scenarios/recursive_caller_egld_1.scen.json +++ b/contracts/feature-tests/composability/scenarios/recursive_caller_egld_1.scen.json @@ -71,6 +71,8 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", + "str:EGLD", + "0", "1" ], "data": [ diff --git a/contracts/feature-tests/composability/scenarios/recursive_caller_esdt_1.scen.json b/contracts/feature-tests/composability/scenarios/recursive_caller_esdt_1.scen.json index 0e4abad4a4..92b883c229 100644 --- a/contracts/feature-tests/composability/scenarios/recursive_caller_esdt_1.scen.json +++ b/contracts/feature-tests/composability/scenarios/recursive_caller_esdt_1.scen.json @@ -79,7 +79,6 @@ "endpoint": "str:accept_funds", "topics": [ "str:accept_funds", - "0", "str:REC-TOKEN", "0", "1" diff --git a/contracts/feature-tests/composability/vault/src/vault.rs b/contracts/feature-tests/composability/vault/src/vault.rs index e700ebda36..8668864de6 100644 --- a/contracts/feature-tests/composability/vault/src/vault.rs +++ b/contracts/feature-tests/composability/vault/src/vault.rs @@ -52,7 +52,7 @@ pub trait Vault { fn all_transfers_multi(&self) -> MultiValueEncoded { self.call_value() - .all_multi_transfers() + .all_transfers() .clone_value() .into_multi_value() } @@ -61,7 +61,7 @@ pub trait Vault { #[endpoint] fn accept_funds(&self) { let esdt_transfers_multi = self.all_transfers_multi(); - self.accept_funds_event(&self.call_value().egld_value(), &esdt_transfers_multi); + self.accept_funds_event(&esdt_transfers_multi); self.call_counts(ManagedBuffer::from(b"accept_funds")) .update(|c| *c += 1); @@ -71,15 +71,14 @@ pub trait Vault { #[endpoint] fn accept_funds_echo_payment( &self, - ) -> MultiValue2> { - let egld_value = self.call_value().egld_value(); + ) -> MultiValueEncoded { let esdt_transfers_multi = self.all_transfers_multi(); - self.accept_funds_event(&egld_value, &esdt_transfers_multi); + self.accept_funds_event(&esdt_transfers_multi); self.call_counts(ManagedBuffer::from(b"accept_funds_echo_payment")) .update(|c| *c += 1); - (egld_value.clone_value(), esdt_transfers_multi).into() + esdt_transfers_multi } #[payable("*")] @@ -92,7 +91,7 @@ pub trait Vault { #[endpoint] fn reject_funds(&self) { let esdt_transfers_multi = self.all_transfers_multi(); - self.reject_funds_event(&self.call_value().egld_value(), &esdt_transfers_multi); + self.reject_funds_event(&esdt_transfers_multi); sc_panic!("reject_funds"); } @@ -258,14 +257,12 @@ pub trait Vault { #[event("accept_funds")] fn accept_funds_event( &self, - #[indexed] egld_value: &BigUint, #[indexed] multi_esdt: &MultiValueEncoded, ); #[event("reject_funds")] fn reject_funds_event( &self, - #[indexed] egld_value: &BigUint, #[indexed] multi_esdt: &MultiValueEncoded, ); diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 43f798acbc..dea8246d00 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -165,16 +165,6 @@ where unsafe { ManagedRef::wrap_handle(all_transfers_handle) } } - /// Same as `all_transfers`, but without EGLD singleton. - /// - /// Temporary! - pub fn all_multi_transfers( - &self, - ) -> ManagedRef<'static, A, ManagedVec>> { - let all_transfers_unchecked_handle = self.all_esdt_transfers_unchecked(); - unsafe { ManagedRef::wrap_handle(all_transfers_unchecked_handle) } - } - /// Verify and casts the received multi ESDT transfer in to an array. /// /// Can be used to extract all payments in one line like this: From b823eb4dcce7b4c9c54d9fc9b54ef62b5116fb98 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 6 Jan 2025 17:57:48 +0200 Subject: [PATCH 122/133] removed unnecessary bounds check in to_array_of_refs/multi_esdt --- framework/base/src/types/managed/wrapped/managed_vec.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 0b32d308e1..5692a5f090 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -171,7 +171,10 @@ where unsafe { MaybeUninit::<[MaybeUninit>; N]>::uninit().assume_init() }; for (index, value) in self.iter().enumerate() { - result_uninit[index].write(value); + // length already checked + unsafe { + result_uninit.get_unchecked_mut(index).write(value); + } } let result = unsafe { transmute_copy(&ManuallyDrop::new(result_uninit)) }; From 6f5455c1771d36d05116013cbe213c40ce0478fc Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 6 Jan 2025 23:29:24 +0200 Subject: [PATCH 123/133] call value - multi_egld_or_esdt, all_esdt_transfers bugfix, tests --- .../composability/vault/src/vault.rs | 4 +- .../call-value-check-multi-egld.scen.json | 5 +-- .../scenarios/call-value-check.scen.json | 6 +-- .../scenarios/payable_all_transfers.scen.json | 12 +++--- .../scenarios/payable_multi_array.scen.json | 42 +++++++++++++++++-- .../payable_multi_array_egld.scen.json | 16 +++---- .../scenarios/payable_multiple.scen.json | 40 ++++++++++++++++++ .../scenarios/payable_multiple_egld.scen.json | 6 +-- .../scenarios/payable_token_5.scen.json | 2 +- .../payable-features/src/payable_features.rs | 35 +++++++++++----- .../src/payable_features_proxy.rs | 38 ++++++++++++----- .../tests/payable_blackbox_test.rs | 4 +- .../payable-features/wasm/src/lib.rs | 10 +++-- .../api/managed_types/static_var_api_flags.rs | 7 ++-- .../wrappers/call_value_wrapper.rs | 19 ++++++++- framework/base/src/err_msg.rs | 1 + 16 files changed, 185 insertions(+), 62 deletions(-) diff --git a/contracts/feature-tests/composability/vault/src/vault.rs b/contracts/feature-tests/composability/vault/src/vault.rs index 8668864de6..47d7406ac4 100644 --- a/contracts/feature-tests/composability/vault/src/vault.rs +++ b/contracts/feature-tests/composability/vault/src/vault.rs @@ -69,9 +69,7 @@ pub trait Vault { #[payable("*")] #[endpoint] - fn accept_funds_echo_payment( - &self, - ) -> MultiValueEncoded { + fn accept_funds_echo_payment(&self) -> MultiValueEncoded { let esdt_transfers_multi = self.all_transfers_multi(); self.accept_funds_event(&esdt_transfers_multi); diff --git a/contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json b/contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json index fd8730d1fc..dda990f1d3 100644 --- a/contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/call-value-check-multi-egld.scen.json @@ -28,7 +28,7 @@ }, { "step": "scCall", - "id": "call-value-multi-esdt", + "id": "call-value-multi-egld-esdt", "tx": { "from": "address:an-account", "to": "sc:payable-features", @@ -58,7 +58,6 @@ }, "expect": { "out": [ - "0", [ "nested:str:EGLD|u64:0|biguint:15", "nested:str:TOK-123456|u64:0|biguint:100", @@ -73,4 +72,4 @@ } } ] -} \ No newline at end of file +} diff --git a/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json b/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json index 23da3773d6..9467a7c0b9 100644 --- a/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json @@ -33,7 +33,7 @@ "from": "address:an-account", "to": "sc:payable-features", "egldValue": "100", - "function": "echo_call_value", + "function": "echo_call_value_legacy", "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" @@ -61,7 +61,7 @@ "value": "100" } ], - "function": "echo_call_value", + "function": "echo_call_value_legacy", "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" @@ -100,7 +100,7 @@ "value": "10" } ], - "function": "echo_call_value", + "function": "echo_call_value_legacy", "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" diff --git a/contracts/feature-tests/payable-features/scenarios/payable_all_transfers.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_all_transfers.scen.json index 8056c49898..3635ec0d6b 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_all_transfers.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_all_transfers.scen.json @@ -39,7 +39,9 @@ "gasPrice": "0" }, "expect": { - "out": [""], + "out": [ + "" + ], "status": "", "logs": "*", "gas": "*", @@ -87,9 +89,7 @@ } ], "function": "payable_all_transfers", - "arguments": [ - - ], + "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" }, @@ -136,9 +136,7 @@ } ], "function": "payable_all_transfers", - "arguments": [ - - ], + "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" }, diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json index b05028dfae..73c4c97e71 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json @@ -54,7 +54,7 @@ "value": "10" } ], - "function": "payment_array_3", + "function": "payment_array_esdt_3", "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" @@ -85,7 +85,7 @@ "value": "10" } ], - "function": "payment_array_3", + "function": "payment_array_esdt_3", "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" @@ -99,6 +99,42 @@ "refund": "*" } }, + { + "step": "scCall", + "id": "payment-array-bad-egld", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:TOK-000003", + "value": "400" + }, + { + "tokenIdentifier": "str:SFT-123", + "nonce": "5", + "value": "10" + }, + { + "tokenIdentifier": "str:EGLD-000000", + "nonce": "0", + "value": "103" + } + ], + "function": "payment_array_esdt_3", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:unexpected EGLD transfer", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, { "step": "scCall", "id": "payment-array-ok", @@ -120,7 +156,7 @@ "value": "10" } ], - "function": "payment_array_3", + "function": "payment_array_esdt_3", "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json index 8daad198aa..c570ab2c4a 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multi_array_egld.scen.json @@ -31,7 +31,7 @@ }, { "step": "scCall", - "id": "payment-array-too-many", + "id": "payment-array-egld-too-many", "tx": { "from": "address:an-account", "to": "sc:payable-features", @@ -59,7 +59,7 @@ "value": "103" } ], - "function": "payment_array_3", + "function": "payment_array_egld_esdt_3", "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" @@ -67,7 +67,7 @@ "expect": { "out": [], "status": "4", - "message": "str:incorrect number of ESDT transfers", + "message": "str:incorrect number of transfers", "logs": "*", "gas": "*", "refund": "*" @@ -75,7 +75,7 @@ }, { "step": "scCall", - "id": "payment-array-too-few", + "id": "payment-array-egld-too-few", "tx": { "from": "address:an-account", "to": "sc:payable-features", @@ -90,7 +90,7 @@ "value": "10" } ], - "function": "payment_array_3", + "function": "payment_array_egld_esdt_3", "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" @@ -98,7 +98,7 @@ "expect": { "out": [], "status": "4", - "message": "str:incorrect number of ESDT transfers", + "message": "str:incorrect number of transfers", "logs": "*", "gas": "*", "refund": "*" @@ -125,7 +125,7 @@ "value": "10" } ], - "function": "payment_array_3", + "function": "payment_array_egld_esdt_3", "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" @@ -143,4 +143,4 @@ } } ] -} \ No newline at end of file +} diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json index 45d92e9fa7..fcbb8ad385 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json @@ -67,6 +67,46 @@ "gas": "*", "refund": "*" } + }, + { + "step": "scCall", + "id": "payment-multiple-bad-egld", + "tx": { + "from": "address:an-account", + "to": "sc:payable-features", + "esdtValue": [ + { + "tokenIdentifier": "str:TOK-123456", + "value": "100" + }, + { + "tokenIdentifier": "str:OTHERTOK-123456", + "value": "100" + }, + { + "tokenIdentifier": "str:SFT-123", + "nonce": "5", + "value": "10" + }, + { + "tokenIdentifier": "str:EGLD-000000", + "nonce": "0", + "value": "120" + } + ], + "function": "payment_multiple", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:unexpected EGLD transfer", + "logs": "*", + "gas": "*", + "refund": "*" + } } ] } diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json index 3cfc600eab..dc10bb4079 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multiple_egld.scen.json @@ -30,7 +30,7 @@ }, { "step": "scCall", - "id": "payment-multiple", + "id": "payment-multiple-egld", "tx": { "from": "address:an-account", "to": "sc:payable-features", @@ -54,7 +54,7 @@ "value": "120" } ], - "function": "payment_multiple", + "function": "payable_all_transfers", "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" @@ -75,4 +75,4 @@ } } ] -} \ No newline at end of file +} diff --git a/contracts/feature-tests/payable-features/scenarios/payable_token_5.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_token_5.scen.json index 6193d505e4..e1eb7abf5a 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_token_5.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_token_5.scen.json @@ -117,4 +117,4 @@ } } ] -} \ No newline at end of file +} diff --git a/contracts/feature-tests/payable-features/src/payable_features.rs b/contracts/feature-tests/payable-features/src/payable_features.rs index 0ffcaa94ec..27ecd1f439 100644 --- a/contracts/feature-tests/payable-features/src/payable_features.rs +++ b/contracts/feature-tests/payable-features/src/payable_features.rs @@ -14,9 +14,7 @@ pub trait PayableFeatures { #[view] #[payable("*")] - fn echo_call_value( - &self, - ) -> MultiValue2>> { + fn echo_call_value_legacy(&self) -> MultiValue2> { ( self.call_value().egld_value().clone_value(), self.call_value().all_esdt_transfers().clone_value(), @@ -24,6 +22,12 @@ pub trait PayableFeatures { .into() } + #[view] + #[payable("*")] + fn echo_call_value(&self) -> ManagedVec { + self.call_value().all_transfers().clone_value() + } + #[endpoint] #[payable("*")] fn payment_multiple( @@ -35,11 +39,28 @@ pub trait PayableFeatures { #[endpoint] #[payable("*")] - fn payment_array_3(&self) -> MultiValue3 { + fn payable_all_transfers(&self) -> ManagedVec { + self.call_value().all_transfers().clone() + } + + #[endpoint] + #[payable("*")] + fn payment_array_esdt_3( + &self, + ) -> MultiValue3 { let [payment_a, payment_b, payment_c] = self.call_value().multi_esdt(); (payment_a.clone(), payment_b.clone(), payment_c.clone()).into() } + #[endpoint] + #[payable("*")] + fn payment_array_egld_esdt_3( + &self, + ) -> MultiValue3 { + let [payment_a, payment_b, payment_c] = self.call_value().multi_egld_or_esdt(); + (payment_a.clone(), payment_b.clone(), payment_c.clone()).into() + } + #[endpoint] #[payable("*")] fn payable_any_1( @@ -152,10 +173,4 @@ pub trait PayableFeatures { let token = self.call_value().single_esdt().token_identifier.clone(); (payment, token).into() } - - #[endpoint] - #[payable("*")] - fn payable_all_transfers(&self) -> ManagedVec { - self.call_value().all_transfers().clone() - } } diff --git a/contracts/feature-tests/payable-features/src/payable_features_proxy.rs b/contracts/feature-tests/payable-features/src/payable_features_proxy.rs index 936752a561..c8fe1834ed 100644 --- a/contracts/feature-tests/payable-features/src/payable_features_proxy.rs +++ b/contracts/feature-tests/payable-features/src/payable_features_proxy.rs @@ -62,9 +62,17 @@ where To: TxTo, Gas: TxGas, { - pub fn echo_call_value( + pub fn echo_call_value_legacy( self, ) -> TxTypedCall, ManagedVec>>> { + self.wrapped_tx + .raw_call("echo_call_value_legacy") + .original_result() + } + + pub fn echo_call_value( + self, + ) -> TxTypedCall>> { self.wrapped_tx .raw_call("echo_call_value") .original_result() @@ -78,11 +86,27 @@ where .original_result() } - pub fn payment_array_3( + pub fn payable_all_transfers( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .raw_call("payable_all_transfers") + .original_result() + } + + pub fn payment_array_esdt_3( self, ) -> TxTypedCall, EsdtTokenPayment, EsdtTokenPayment>> { self.wrapped_tx - .raw_call("payment_array_3") + .raw_call("payment_array_esdt_3") + .original_result() + } + + pub fn payment_array_egld_esdt_3( + self, + ) -> TxTypedCall, EgldOrEsdtTokenPayment, EgldOrEsdtTokenPayment>> { + self.wrapped_tx + .raw_call("payment_array_egld_esdt_3") .original_result() } @@ -181,12 +205,4 @@ where .raw_call("payable_token_4") .original_result() } - - pub fn payable_all_transfers( - self, - ) -> TxTypedCall>> { - self.wrapped_tx - .raw_call("payable_all_transfers") - .original_result() - } } diff --git a/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs b/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs index b56dc46aaa..53069825f4 100644 --- a/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs +++ b/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs @@ -18,7 +18,7 @@ fn world() -> ScenarioWorld { } #[test] -fn payable_multi() { +fn payable_multi_legacy() { let mut world = world(); world @@ -43,7 +43,7 @@ fn payable_multi() { .from(USER) .to(PAYABLE_FEATURES_ADDRESS) .typed(payable_features_proxy::PayableFeaturesProxy) - .echo_call_value() + .echo_call_value_legacy() .esdt(TestEsdtTransfer(TOKEN_1, 0, 100)) .esdt(TestEsdtTransfer(TOKEN_2, 0, 400)) .returns(ReturnsResultUnmanaged) diff --git a/contracts/feature-tests/payable-features/wasm/src/lib.rs b/contracts/feature-tests/payable-features/wasm/src/lib.rs index 67b35b5de8..bf30b04490 100644 --- a/contracts/feature-tests/payable-features/wasm/src/lib.rs +++ b/contracts/feature-tests/payable-features/wasm/src/lib.rs @@ -5,9 +5,9 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 16 +// Endpoints: 18 // Async Callback (empty): 1 -// Total number of exported functions: 18 +// Total number of exported functions: 20 #![no_std] @@ -18,9 +18,12 @@ multiversx_sc_wasm_adapter::endpoints! { payable_features ( init => init + echo_call_value_legacy => echo_call_value_legacy echo_call_value => echo_call_value payment_multiple => payment_multiple - payment_array_3 => payment_array_3 + payable_all_transfers => payable_all_transfers + payment_array_esdt_3 => payment_array_esdt_3 + payment_array_egld_esdt_3 => payment_array_egld_esdt_3 payable_any_1 => payable_any_1 payable_any_2 => payable_any_2 payable_any_3 => payable_any_3 @@ -33,7 +36,6 @@ multiversx_sc_wasm_adapter::endpoints! { payable_token_2 => payable_token_2 payable_token_3 => payable_token_3 payable_token_4 => payable_token_4 - payable_all_transfers => payable_all_transfers ) } diff --git a/framework/base/src/api/managed_types/static_var_api_flags.rs b/framework/base/src/api/managed_types/static_var_api_flags.rs index 2040d8acf3..334381e32e 100644 --- a/framework/base/src/api/managed_types/static_var_api_flags.rs +++ b/framework/base/src/api/managed_types/static_var_api_flags.rs @@ -6,9 +6,10 @@ bitflags! { const NONE = 0b00000000; const CALL_VALUE_EGLD_SINGLE_INITIALIZED = 0b00000001; const CALL_VALUE_ESDT_UNCHECKED_INITIALIZED = 0b00000010; - const CALL_VALUE_EGLD_MULTI_INITIALIZED = 0b00000100; - const CALL_VALUE_EGLD_FROM_ESDT_INITIALIZED = 0b00001000; - const CALL_VALUE_ALL_INITIALIZED = 0b00010000; + const CALL_VALUE_ESDT_INITIALIZED = 0b00000100; + const CALL_VALUE_EGLD_MULTI_INITIALIZED = 0b00001000; + const CALL_VALUE_EGLD_FROM_ESDT_INITIALIZED = 0b00010000; + const CALL_VALUE_ALL_INITIALIZED = 0b00100000; } } diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index dea8246d00..e811e8bd15 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -119,7 +119,7 @@ where pub fn all_esdt_transfers(&self) -> ManagedRef<'static, A, ManagedVec>> { let multi_esdt_handle: A::ManagedBufferHandle = self.all_esdt_transfers_unchecked(); if !A::static_var_api_impl() - .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_ESDT_UNCHECKED_INITIALIZED) + .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_ESDT_INITIALIZED) { let egld_value_multi_handle = self.egld_from_multi_esdt(); if bi_gt_zero::(egld_value_multi_handle) { @@ -170,6 +170,8 @@ where /// Can be used to extract all payments in one line like this: /// /// `let [payment_a, payment_b, payment_c] = self.call_value().multi_esdt();`. + /// + /// Rejects EGLD transfers. Switch to `multi_egld_or_esdt` to accept mixed transfers. pub fn multi_esdt(&self) -> [ManagedVecRef<'static, EsdtTokenPayment>; N] { let esdt_transfers = self.all_esdt_transfers(); let array = esdt_transfers.to_array_of_refs::().unwrap_or_else(|| { @@ -178,6 +180,21 @@ where unsafe { core::mem::transmute(array) } } + /// Verify and casts the received multi ESDT transfer in to an array. + /// + /// Can be used to extract all payments in one line like this: + /// + /// `let [payment_a, payment_b, payment_c] = self.call_value().multi_egld_or_esdt();`. + pub fn multi_egld_or_esdt( + &self, + ) -> [ManagedVecRef<'static, EgldOrEsdtTokenPayment>; N] { + let esdt_transfers = self.all_transfers(); + let array = esdt_transfers.to_array_of_refs::().unwrap_or_else(|| { + A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_TRANSFERS.as_bytes()) + }); + unsafe { core::mem::transmute(array) } + } + /// Expects precisely one ESDT token transfer, fungible or not. /// /// Will return the received ESDT payment. diff --git a/framework/base/src/err_msg.rs b/framework/base/src/err_msg.rs index 019a0c325e..77f6a8bad3 100644 --- a/framework/base/src/err_msg.rs +++ b/framework/base/src/err_msg.rs @@ -9,6 +9,7 @@ pub const TOO_MANY_ESDT_TRANSFERS: &str = "too many ESDT transfers"; pub const ESDT_INVALID_TOKEN_INDEX: &str = "invalid token index"; pub const ESDT_UNEXPECTED_EGLD: &str = "unexpected EGLD transfer"; pub const INCORRECT_NUM_ESDT_TRANSFERS: &str = "incorrect number of ESDT transfers"; +pub const INCORRECT_NUM_TRANSFERS: &str = "incorrect number of transfers"; pub const FUNGIBLE_TOKEN_EXPECTED_ERR_MSG: &str = "fungible ESDT token expected"; pub const TOKEN_IDENTIFIER_ESDT_EXPECTED: &str = "ESDT expected"; From f101b8221eb09fa284d953b67cc6286500543a43 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 6 Jan 2025 23:40:59 +0200 Subject: [PATCH 124/133] actions.yml fix --- .github/workflows/actions.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 225a894772..d59c19bfd6 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -19,6 +19,7 @@ jobs: rust-toolchain: 1.82 path-to-sc-meta: framework/meta mx-scenario-go-version: v3.0.0 + wabt-version: 1.0.32-1 # TODO: no longer needed, remove completely coverage-args: --ignore-filename-regex='meta/src' --ignore-filename-regex='wasm-adapter' --ignore-filename-regex='benchmarks/' --ignore-filename-regex='tests/' --output ./coverage.md secrets: token: ${{ secrets.GITHUB_TOKEN }} From d3d4b8219f522e2108e05315d5ee4c598d313c99 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 7 Jan 2025 00:09:06 +0200 Subject: [PATCH 125/133] github actions - remove wabt --- .github/workflows/actions-nightly.yml | 2 +- .github/workflows/actions.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/actions-nightly.yml b/.github/workflows/actions-nightly.yml index 1569c9a99c..23d4f9f5d7 100644 --- a/.github/workflows/actions-nightly.yml +++ b/.github/workflows/actions-nightly.yml @@ -14,7 +14,7 @@ permissions: jobs: contracts: name: Contracts (nightly) - uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v4.1.1 + uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@eb65c5cae88d1d540f1603c0cabc428fbe9e0975 with: rust-toolchain: nightly-2024-05-22 path-to-sc-meta: framework/meta diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 225a894772..031cea0f1a 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -14,7 +14,7 @@ permissions: jobs: contracts: name: Contracts - uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@72dc7659e6945c8749d01ec28638843bae33437e + uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@eb65c5cae88d1d540f1603c0cabc428fbe9e0975 with: rust-toolchain: 1.82 path-to-sc-meta: framework/meta From 4206c01f79242ab9f04767118eaa89ea7a4bbfdb Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 7 Jan 2025 00:40:12 +0200 Subject: [PATCH 126/133] pltter-test.yml fix --- .github/workflows/plotter-test.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/plotter-test.yml b/.github/workflows/plotter-test.yml index a6b948361d..9383c82247 100644 --- a/.github/workflows/plotter-test.yml +++ b/.github/workflows/plotter-test.yml @@ -24,6 +24,10 @@ jobs: toolchain: 1.82 target: wasm32-unknown-unknown + - name: Prerequisites + run: | + sudo apt install pkg-config libfreetype6-dev libfontconfig1-dev + - name: Run plotter tests run: | cd tools/plotter From 85c0077c6521c6310fb5841f83cfed83dd1cec1c Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 7 Jan 2025 01:08:02 +0200 Subject: [PATCH 127/133] actions cleanup --- .github/workflows/actions.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index d0906ea4ad..031cea0f1a 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -19,7 +19,6 @@ jobs: rust-toolchain: 1.82 path-to-sc-meta: framework/meta mx-scenario-go-version: v3.0.0 - wabt-version: 1.0.32-1 # TODO: no longer needed, remove completely coverage-args: --ignore-filename-regex='meta/src' --ignore-filename-regex='wasm-adapter' --ignore-filename-regex='benchmarks/' --ignore-filename-regex='tests/' --output ./coverage.md secrets: token: ${{ secrets.GITHUB_TOKEN }} From cbb75bf1415c59438ee374db5137fa1aa4bf5abb Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 8 Jan 2025 01:35:50 +0200 Subject: [PATCH 128/133] call value - simplified egld handling --- .../api/managed_types/static_var_api_flags.rs | 18 ++-- .../wrappers/call_value_wrapper.rs | 85 ++++--------------- 2 files changed, 25 insertions(+), 78 deletions(-) diff --git a/framework/base/src/api/managed_types/static_var_api_flags.rs b/framework/base/src/api/managed_types/static_var_api_flags.rs index 334381e32e..813dea9e4c 100644 --- a/framework/base/src/api/managed_types/static_var_api_flags.rs +++ b/framework/base/src/api/managed_types/static_var_api_flags.rs @@ -4,12 +4,10 @@ bitflags! { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct StaticVarApiFlags: u8 { const NONE = 0b00000000; - const CALL_VALUE_EGLD_SINGLE_INITIALIZED = 0b00000001; + const CALL_VALUE_EGLD_DIRECT_INITIALIZED = 0b00000001; const CALL_VALUE_ESDT_UNCHECKED_INITIALIZED = 0b00000010; const CALL_VALUE_ESDT_INITIALIZED = 0b00000100; - const CALL_VALUE_EGLD_MULTI_INITIALIZED = 0b00001000; - const CALL_VALUE_EGLD_FROM_ESDT_INITIALIZED = 0b00010000; - const CALL_VALUE_ALL_INITIALIZED = 0b00100000; + const CALL_VALUE_ALL_INITIALIZED = 0b00001000; } } @@ -34,27 +32,27 @@ pub mod tests { assert!(current.check_and_set(StaticVarApiFlags::NONE)); assert_eq!(current, StaticVarApiFlags::NONE); - assert!(!current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED)); + assert!(!current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_DIRECT_INITIALIZED)); assert_eq!( current, - StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED + StaticVarApiFlags::CALL_VALUE_EGLD_DIRECT_INITIALIZED ); - assert!(current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED)); + assert!(current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_DIRECT_INITIALIZED)); assert_eq!( current, - StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED + StaticVarApiFlags::CALL_VALUE_EGLD_DIRECT_INITIALIZED ); assert!(!current.check_and_set(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED)); assert_eq!( current, - StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED + StaticVarApiFlags::CALL_VALUE_EGLD_DIRECT_INITIALIZED | StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED ); assert!(current.check_and_set(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED)); assert_eq!( current, - StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED + StaticVarApiFlags::CALL_VALUE_EGLD_DIRECT_INITIALIZED | StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED ); } diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index e811e8bd15..043b37e7f4 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -9,7 +9,7 @@ use crate::{ }, err_msg, types::{ - big_num_cmp::bi_gt_zero, BigInt, BigUint, ConstDecimals, EgldOrEsdtTokenIdentifier, + big_num_cmp::bi_gt_zero, BigUint, ConstDecimals, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, EsdtTokenPayment, ManagedDecimal, ManagedRef, ManagedType, ManagedVec, ManagedVecItem, ManagedVecItemPayload, ManagedVecPayloadIterator, ManagedVecRef, TokenIdentifier, @@ -47,38 +47,21 @@ where all_transfers_unchecked_handle } - /// Cached egld transfer searched for in the ESDT transfers from the VM. - fn egld_from_multi_esdt(&self) -> A::BigIntHandle { - let egld_from_multi_esdt_handle: A::BigIntHandle = - use_raw_handle(const_handles::CALL_VALUE_EGLD_FROM_ESDT); + fn egld_value_unchecked(&self) -> ManagedRef<'static, A, BigUint> { + let call_value_handle: A::BigIntHandle = use_raw_handle(const_handles::CALL_VALUE_EGLD); if !A::static_var_api_impl() - .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_FROM_ESDT_INITIALIZED) + .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_DIRECT_INITIALIZED) { - let all_transfers_unchecked_handle = self.all_esdt_transfers_unchecked(); - let egld_handle_result = find_egld_000000_transfer::(all_transfers_unchecked_handle); - if let Some(found_egld_handle) = egld_handle_result { - BigInt::::clone_to_handle( - use_raw_handle(found_egld_handle), - egld_from_multi_esdt_handle.clone(), - ); - } else { - BigInt::::set_value(egld_from_multi_esdt_handle.clone(), 0); - } + A::call_value_api_impl().load_egld_value(call_value_handle.clone()); } - egld_from_multi_esdt_handle + unsafe { ManagedRef::wrap_handle(call_value_handle) } } /// Retrieves the EGLD call value from the VM. /// /// Will return 0 in case of an ESDT transfer, even though EGLD and ESDT transfers are now posible. pub fn egld_value(&self) -> ManagedRef<'static, A, BigUint> { - let call_value_handle: A::BigIntHandle = use_raw_handle(const_handles::CALL_VALUE_EGLD); - if !A::static_var_api_impl() - .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_SINGLE_INITIALIZED) - { - A::call_value_api_impl().load_egld_value(call_value_handle.clone()); - } - unsafe { ManagedRef::wrap_handle(call_value_handle) } + self.egld_value_unchecked() } /// Returns the EGLD call value from the VM as ManagedDecimal @@ -88,43 +71,16 @@ where ) } - /// The quantity of EGLD transfered, either via simple EGLD transfer, or via ESDT multi-transfer. - pub fn egld_value_multi(&self) -> ManagedRef<'static, A, BigUint> { - let egld_value_multi_handle: A::BigIntHandle = - use_raw_handle(const_handles::CALL_VALUE_EGLD_MULTI); - if !A::static_var_api_impl() - .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_MULTI_INITIALIZED) - { - let egld_single = self.egld_value(); - if bi_gt_zero::(egld_single.get_handle()) { - BigInt::::clone_to_handle( - egld_single.get_handle(), - egld_value_multi_handle.clone(), - ); - } else { - let egld_from_multi_esdt_handle = self.egld_from_multi_esdt(); - BigInt::::clone_to_handle( - egld_from_multi_esdt_handle, - egld_value_multi_handle.clone(), - ); - } - } - unsafe { ManagedRef::wrap_handle(egld_value_multi_handle) } - } - /// Returns all ESDT transfers that accompany this SC call. /// Will return 0 results if nothing was transfered, or just EGLD. /// /// Will crash for EGLD + ESDT multi transfers. pub fn all_esdt_transfers(&self) -> ManagedRef<'static, A, ManagedVec>> { let multi_esdt_handle: A::ManagedBufferHandle = self.all_esdt_transfers_unchecked(); - if !A::static_var_api_impl() - .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_ESDT_INITIALIZED) - { - let egld_value_multi_handle = self.egld_from_multi_esdt(); - if bi_gt_zero::(egld_value_multi_handle) { - A::error_api_impl().signal_error(err_msg::ESDT_UNEXPECTED_EGLD.as_bytes()) - } + let checked = A::static_var_api_impl() + .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_ESDT_INITIALIZED); + if !checked && egld_000000_transfer_exists::(multi_esdt_handle.clone()) { + A::error_api_impl().signal_error(err_msg::ESDT_UNEXPECTED_EGLD.as_bytes()) } unsafe { ManagedRef::wrap_handle(multi_esdt_handle) } @@ -144,7 +100,7 @@ where if !A::static_var_api_impl() .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED) { - let egld_single = self.egld_value(); + let egld_single = self.egld_value_unchecked(); if bi_gt_zero::(egld_single.get_handle()) { A::managed_type_impl().mb_overwrite( use_raw_handle(const_handles::MBUF_EGLD_000000), @@ -246,7 +202,7 @@ where 0 => EgldOrEsdtTokenPayment { token_identifier: EgldOrEsdtTokenIdentifier::egld(), token_nonce: 0, - amount: self.egld_value().clone_value(), + amount: self.egld_value_unchecked().clone_value(), }, 1 => esdt_transfers.get(0).clone(), _ => A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_ESDT_TRANSFERS.as_bytes()), @@ -276,14 +232,14 @@ where pub fn any_payment(&self) -> EgldOrMultiEsdtPayment { let esdt_transfers = self.all_esdt_transfers(); if esdt_transfers.is_empty() { - EgldOrMultiEsdtPayment::Egld(self.egld_value().clone_value()) + EgldOrMultiEsdtPayment::Egld(self.egld_value_unchecked().clone_value()) } else { EgldOrMultiEsdtPayment::MultiEsdt(esdt_transfers.clone_value()) } } } -fn find_egld_000000_transfer(transfers_vec_handle: A::ManagedBufferHandle) -> Option +fn egld_000000_transfer_exists(transfers_vec_handle: A::ManagedBufferHandle) -> bool where A: CallValueApi + ErrorApi + ManagedTypeApi, { @@ -297,19 +253,12 @@ where as ManagedVecItem>::PAYLOAD, > = ManagedVecPayloadIterator::new(transfers_vec_handle); - if iter.remaining_count() <= 1 { - // EGLD is not allowed in single transfers - return None; - } - - let egld_payload = iter.find(|payload| { + iter.any(|payload| { let token_identifier_handle = RawHandle::read_from_payload(payload.slice_unchecked(0)); A::managed_type_impl().mb_eq( use_raw_handle(const_handles::MBUF_EGLD_000000), use_raw_handle(token_identifier_handle), ) - }); - - egld_payload.map(|payload| RawHandle::read_from_payload(payload.slice_unchecked(12))) + }) } } From 0f8fd327e3db3b0890ecb7492846ee710271680c Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 8 Jan 2025 15:07:01 +0200 Subject: [PATCH 129/133] call value - single_egld_value --- contracts/core/wegld-swap/src/wegld.rs | 2 +- .../crypto-bubbles/src/crypto_bubbles.rs | 4 +-- .../crypto-kitties/kitty-auction/src/lib.rs | 2 +- .../crypto-kitties/kitty-ownership/src/lib.rs | 2 +- .../crypto-zombies/src/zombie_helper.rs | 2 +- .../digital-cash/src/pay_fee_and_fund.rs | 2 +- .../child/src/lib.rs | 2 +- .../parent/src/lib.rs | 2 +- .../forwarder-legacy/src/fwd_esdt_legacy.rs | 2 +- .../forwarder-legacy/src/fwd_nft_legacy.rs | 2 +- .../forwarder-legacy/src/fwd_sft_legacy.rs | 2 +- .../src/forwarder_raw_alt_init.rs | 2 +- .../forwarder-raw/src/forwarder_raw_async.rs | 2 +- .../forwarder-raw/src/forwarder_raw_sync.rs | 6 ++-- .../forwarder/src/fwd_call_sync.rs | 2 +- .../composability/forwarder/src/fwd_esdt.rs | 2 +- .../composability/forwarder/src/fwd_nft.rs | 2 +- .../composability/forwarder/src/fwd_sft.rs | 2 +- .../local-esdt-and-nft/src/lib.rs | 6 ++-- .../proxy-test-first/src/proxy-test-first.rs | 8 ++--- .../src/proxy-test-second.rs | 6 ++-- .../payable-features/src/payable_features.rs | 6 ++-- .../rust-testing-framework-tester/src/lib.rs | 4 +-- .../tests/use_module_scenario_rs_test.rs | 2 +- contracts/modules/src/dns.rs | 2 +- contracts/modules/src/esdt.rs | 2 +- .../src/token_merge/merged_token_setup.rs | 2 +- .../wrappers/call_value_wrapper.rs | 32 ++++++++++++++++--- framework/base/src/io/call_value_init.rs | 7 ++-- 29 files changed, 70 insertions(+), 49 deletions(-) diff --git a/contracts/core/wegld-swap/src/wegld.rs b/contracts/core/wegld-swap/src/wegld.rs index 1c9cf11a2a..cb07f2b31a 100644 --- a/contracts/core/wegld-swap/src/wegld.rs +++ b/contracts/core/wegld-swap/src/wegld.rs @@ -16,7 +16,7 @@ pub trait EgldEsdtSwap: multiversx_sc_modules::pause::PauseModule { fn wrap_egld(&self) -> EsdtTokenPayment { self.require_not_paused(); - let payment_amount = self.call_value().egld_value(); + let payment_amount = self.call_value().single_egld_value(); require!(*payment_amount > 0u32, "Payment must be more than 0"); let wrapped_egld_token_id = self.wrapped_egld_token_id().get(); diff --git a/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs b/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs index 35b687f2cc..5c5f791633 100644 --- a/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs +++ b/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs @@ -13,7 +13,7 @@ pub trait CryptoBubbles { #[payable("EGLD")] #[endpoint(topUp)] fn top_up(&self) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); let caller = self.blockchain().get_caller(); self.player_balance(&caller) .update(|balance| *balance += &*payment); @@ -63,7 +63,7 @@ pub trait CryptoBubbles { #[payable("EGLD")] #[endpoint(joinGame)] fn join_game(&self, game_index: BigUint) { - let bet = self.call_value().egld_value(); + let bet = self.call_value().single_egld_value(); let player = self.blockchain().get_caller(); self.top_up(); self.add_player_to_game_state_change(&game_index, &player, &bet) diff --git a/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs b/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs index 60a30c382e..aadcfe8c8c 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs @@ -152,7 +152,7 @@ pub trait KittyAuction { #[payable("EGLD")] #[endpoint] fn bid(&self, kitty_id: u32) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); require!( self.is_up_for_auction(kitty_id), diff --git a/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs b/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs index dbde8aed52..b65b2ee5a1 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs @@ -287,7 +287,7 @@ pub trait KittyOwnership { require!(self.is_valid_id(matron_id), "Invalid matron id!"); require!(self.is_valid_id(sire_id), "Invalid sire id!"); - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); let auto_birth_fee = self.birth_fee().get(); let caller = self.blockchain().get_caller(); diff --git a/contracts/examples/crypto-zombies/src/zombie_helper.rs b/contracts/examples/crypto-zombies/src/zombie_helper.rs index c38edc9ea0..ef0e04793a 100644 --- a/contracts/examples/crypto-zombies/src/zombie_helper.rs +++ b/contracts/examples/crypto-zombies/src/zombie_helper.rs @@ -19,7 +19,7 @@ pub trait ZombieHelper: storage::Storage { #[payable("EGLD")] #[endpoint] fn level_up(&self, zombie_id: usize) { - let payment_amount = self.call_value().egld_value(); + let payment_amount = self.call_value().single_egld_value(); let fee = self.level_up_fee().get(); require!(*payment_amount == fee, "Payment must be must be 0.001 EGLD"); self.zombies(&zombie_id) diff --git a/contracts/examples/digital-cash/src/pay_fee_and_fund.rs b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs index 3815ea38cc..2aaf115996 100644 --- a/contracts/examples/digital-cash/src/pay_fee_and_fund.rs +++ b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs @@ -19,7 +19,7 @@ pub trait PayFeeAndFund: storage::StorageModule + helpers::HelpersModule { #[endpoint(payFeeAndFundEGLD)] #[payable("EGLD")] fn pay_fee_and_fund_egld(&self, address: ManagedAddress, valability: u64) { - let mut fund = self.call_value().egld_value().clone_value(); + let mut fund = self.call_value().single_egld_value().clone_value(); let fee_value = self.fee(&EgldOrEsdtTokenIdentifier::egld()).get(); require!(fund > fee_value, "payment not covering fees"); diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs index dcb634f054..d5ff191862 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs @@ -17,7 +17,7 @@ pub trait Child { token_ticker: ManagedBuffer, initial_supply: BigUint, ) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().single_egld_value(); self.send() .esdt_system_sc_proxy() .issue_fungible( diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs index 5c4bff50d0..139a58673c 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs @@ -38,7 +38,7 @@ pub trait Parent { token_ticker: ManagedBuffer, initial_supply: BigUint, ) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().single_egld_value(); let child_contract_adress = self.child_contract_address().get(); self.tx() diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs index 7ba477b448..871d0e5f70 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs @@ -90,7 +90,7 @@ pub trait ForwarderEsdtModule: fwd_storage_legacy::ForwarderStorageModule { token_ticker: ManagedBuffer, initial_supply: BigUint, ) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().single_egld_value(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs index 8e04da46a1..0b8477c3d9 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs @@ -52,7 +52,7 @@ pub trait ForwarderNftModule: fwd_storage_legacy::ForwarderStorageModule { #[payable("EGLD")] #[endpoint] fn nft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().single_egld_value(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs index 41d01c6f7a..f320663e29 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs @@ -7,7 +7,7 @@ pub trait ForwarderSftModule: fwd_storage_legacy::ForwarderStorageModule { #[payable("EGLD")] #[endpoint] fn sft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().single_egld_value(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs index f00a10d434..97f7e8cd11 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs @@ -52,7 +52,7 @@ pub trait ForwarderRawAlterativeInit: super::forwarder_raw_common::ForwarderRawC endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); let half_gas = self.blockchain().get_gas_left() / 2; let result = self 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 df66f30a30..a8e421982a 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 @@ -91,7 +91,7 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); self.forward_contract_call( to, EgldOrEsdtTokenIdentifier::egld(), diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs index 07a095ed9d..ea453ecf9f 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs @@ -10,7 +10,7 @@ pub trait ForwarderRawSync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().egld_value().clone_value(); + let payment = self.call_value().single_egld_value().clone_value(); let half_gas = self.blockchain().get_gas_left() / 2; let result = self .tx() @@ -33,7 +33,7 @@ pub trait ForwarderRawSync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); let one_third_gas = self.blockchain().get_gas_left() / 3; let half_payment = &*payment / 2u32; let arg_buffer = args.to_arg_buffer(); @@ -71,7 +71,7 @@ pub trait ForwarderRawSync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); let half_gas = self.blockchain().get_gas_left() / 2; let result = self 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 d5b6f63492..8b9a30a6be 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs @@ -80,7 +80,7 @@ pub trait ForwarderSyncCallModule { #[endpoint] #[payable("EGLD")] fn forward_sync_accept_funds_rh_egld(&self, to: ManagedAddress) -> BigUint { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); let half_gas = self.blockchain().get_gas_left() / 2; self.tx() diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs b/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs index 425ca07053..7f289e10db 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs @@ -95,7 +95,7 @@ pub trait ForwarderEsdtModule: fwd_storage::ForwarderStorageModule { token_ticker: ManagedBuffer, initial_supply: BigUint, ) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().single_egld_value(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs b/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs index 5358397df9..dc9400a269 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs @@ -52,7 +52,7 @@ pub trait ForwarderNftModule: fwd_storage::ForwarderStorageModule { #[payable("EGLD")] #[endpoint] fn nft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().single_egld_value(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs b/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs index 13d0b3a5ad..832e424527 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs @@ -7,7 +7,7 @@ pub trait ForwarderSftModule: fwd_storage::ForwarderStorageModule { #[payable("EGLD")] #[endpoint] fn sft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().single_egld_value(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs b/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs index e0cf22ab74..311f98c48b 100644 --- a/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs +++ b/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs @@ -27,7 +27,7 @@ pub trait LocalEsdtAndEsdtNft { token_ticker: ManagedBuffer, initial_supply: BigUint, ) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().single_egld_value(); let caller = self.blockchain().get_caller(); self.send() @@ -68,7 +68,7 @@ pub trait LocalEsdtAndEsdtNft { #[payable("EGLD")] #[endpoint(nftIssue)] fn nft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().single_egld_value(); let caller = self.blockchain().get_caller(); self.send() @@ -174,7 +174,7 @@ pub trait LocalEsdtAndEsdtNft { #[payable("EGLD")] #[endpoint(sftIssue)] fn sft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().single_egld_value(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs b/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs index eacc3064d0..7e355d0fe4 100644 --- a/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs +++ b/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs @@ -29,7 +29,7 @@ pub trait ProxyTestFirst { #[payable("EGLD")] #[endpoint(deploySecondContract)] fn deploy_second_contract(&self, code: ManagedBuffer) -> i32 { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); let (address, init_result) = self .tx() @@ -49,7 +49,7 @@ pub trait ProxyTestFirst { #[payable("EGLD")] #[endpoint(upgradeSecondContract)] fn upgrade_second_contract(&self, code: ManagedBuffer) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); let other_contract = self.get_other_contract(); self.tx() @@ -66,7 +66,7 @@ pub trait ProxyTestFirst { #[payable("EGLD")] #[endpoint(forwardToOtherContract)] fn forward_to_other_contract(&self) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); let other_contract = self.get_other_contract(); self.tx() .to(&other_contract) @@ -79,7 +79,7 @@ pub trait ProxyTestFirst { #[payable("EGLD")] #[endpoint(forwardToOtherContractWithCallback)] fn forward_to_other_contract_with_callback(&self) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); let other_contract = self.get_other_contract(); self.tx() .to(&other_contract) diff --git a/contracts/feature-tests/composability/proxy-test-second/src/proxy-test-second.rs b/contracts/feature-tests/composability/proxy-test-second/src/proxy-test-second.rs index 33f199cfb5..f4b0108a48 100644 --- a/contracts/feature-tests/composability/proxy-test-second/src/proxy-test-second.rs +++ b/contracts/feature-tests/composability/proxy-test-second/src/proxy-test-second.rs @@ -28,7 +28,7 @@ pub trait ProxyTestSecond { #[init] #[payable("EGLD")] fn init(&self, init_arg: i32) -> i32 { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); self.set_last_payment(&payment); self.set_init_arg(init_arg); init_arg + 1 @@ -43,7 +43,7 @@ pub trait ProxyTestSecond { #[payable("EGLD")] #[endpoint(payMe)] fn pay_me(&self, arg1: i64) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); self.set_last_payment(&payment); self.set_pay_me_arg(arg1); } @@ -51,7 +51,7 @@ pub trait ProxyTestSecond { #[payable("EGLD")] #[endpoint(payMeWithResult)] fn pay_me_with_result_endpoint(&self, arg1: i64) -> i64 { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); self.set_last_payment(&payment); self.set_pay_me_arg(arg1); diff --git a/contracts/feature-tests/payable-features/src/payable_features.rs b/contracts/feature-tests/payable-features/src/payable_features.rs index 27ecd1f439..7559b21f54 100644 --- a/contracts/feature-tests/payable-features/src/payable_features.rs +++ b/contracts/feature-tests/payable-features/src/payable_features.rs @@ -104,7 +104,7 @@ pub trait PayableFeatures { &self, #[payment_token] token: EgldOrEsdtTokenIdentifier, ) -> MultiValue2 { - let payment = self.call_value().egld_value().clone_value(); + let payment = self.call_value().single_egld_value().clone_value(); (payment, token).into() } @@ -124,14 +124,14 @@ pub trait PayableFeatures { &self, #[payment_token] token: EgldOrEsdtTokenIdentifier, ) -> MultiValue2 { - let payment = self.call_value().egld_value().clone_value(); + let payment = self.call_value().single_egld_value().clone_value(); (payment, token).into() } #[endpoint] #[payable("EGLD")] fn payable_egld_4(&self) -> MultiValue2 { - let payment = self.call_value().egld_value(); + let payment = self.call_value().single_egld_value(); let token = self.call_value().egld_or_single_esdt().token_identifier; (payment.clone_value(), token).into() } diff --git a/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs b/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs index 9d7be05858..c62cce964c 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs @@ -57,13 +57,13 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[payable("EGLD")] #[endpoint] fn receive_egld(&self) -> BigUint { - self.call_value().egld_value().clone_value() + self.call_value().single_egld_value().clone_value() } #[payable("EGLD")] #[endpoint] fn recieve_egld_half(&self) { - let payment_amount = &*self.call_value().egld_value() / 2u32; + let payment_amount = &*self.call_value().single_egld_value() / 2u32; self.tx().to(ToCaller).egld(payment_amount).transfer(); } diff --git a/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs b/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs index 7a14793c46..5e68116633 100644 --- a/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs +++ b/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs @@ -6,7 +6,7 @@ mod dns_mock { #[payable("EGLD")] #[endpoint] fn register(&self, name: BoxedBytes) { - let _payment = self.call_value().egld_value(); + let _payment = self.call_value().single_egld_value(); let address = self.blockchain().get_caller(); self.tx() .to(&address) diff --git a/contracts/modules/src/dns.rs b/contracts/modules/src/dns.rs index 7e8123a0cf..20cf5e63fe 100644 --- a/contracts/modules/src/dns.rs +++ b/contracts/modules/src/dns.rs @@ -13,7 +13,7 @@ pub trait DnsModule { #[only_owner] #[endpoint(dnsRegister)] fn dns_register(&self, dns_address: ManagedAddress, name: ManagedBuffer) { - let payment = self.call_value().egld_value().clone_value(); + let payment = self.call_value().single_egld_value().clone_value(); self.tx() .to(&dns_address) .typed(dns_proxy::DnsProxy) diff --git a/contracts/modules/src/esdt.rs b/contracts/modules/src/esdt.rs index 42314e9608..e38307c450 100644 --- a/contracts/modules/src/esdt.rs +++ b/contracts/modules/src/esdt.rs @@ -34,7 +34,7 @@ pub trait EsdtModule { ) { require!(self.token_id().is_empty(), "Token already issued"); - let issue_cost = self.call_value().egld_value().clone_value(); + let issue_cost = self.call_value().single_egld_value().clone_value(); let num_decimals = match opt_num_decimals { OptionalValue::Some(d) => d, OptionalValue::None => 0, diff --git a/contracts/modules/src/token_merge/merged_token_setup.rs b/contracts/modules/src/token_merge/merged_token_setup.rs index f99618e073..309c924ddb 100644 --- a/contracts/modules/src/token_merge/merged_token_setup.rs +++ b/contracts/modules/src/token_merge/merged_token_setup.rs @@ -14,7 +14,7 @@ pub trait MergedTokenSetupModule { #[payable("EGLD")] #[endpoint(issueMergedToken)] fn issue_merged_token(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let payment_amount = self.call_value().egld_value(); + let payment_amount = self.call_value().single_egld_value(); self.merged_token().issue_and_set_all_roles( EsdtTokenType::NonFungible, payment_amount.clone_value(), diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 043b37e7f4..65e49b34f9 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -47,7 +47,7 @@ where all_transfers_unchecked_handle } - fn egld_value_unchecked(&self) -> ManagedRef<'static, A, BigUint> { + fn egld_value_direct_unchecked(&self) -> ManagedRef<'static, A, BigUint> { let call_value_handle: A::BigIntHandle = use_raw_handle(const_handles::CALL_VALUE_EGLD); if !A::static_var_api_impl() .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_DIRECT_INITIALIZED) @@ -61,7 +61,7 @@ where /// /// Will return 0 in case of an ESDT transfer, even though EGLD and ESDT transfers are now posible. pub fn egld_value(&self) -> ManagedRef<'static, A, BigUint> { - self.egld_value_unchecked() + self.egld_value_direct_unchecked() } /// Returns the EGLD call value from the VM as ManagedDecimal @@ -100,7 +100,7 @@ where if !A::static_var_api_impl() .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED) { - let egld_single = self.egld_value_unchecked(); + let egld_single = self.egld_value_direct_unchecked(); if bi_gt_zero::(egld_single.get_handle()) { A::managed_type_impl().mb_overwrite( use_raw_handle(const_handles::MBUF_EGLD_000000), @@ -202,13 +202,35 @@ where 0 => EgldOrEsdtTokenPayment { token_identifier: EgldOrEsdtTokenIdentifier::egld(), token_nonce: 0, - amount: self.egld_value_unchecked().clone_value(), + amount: self.egld_value_direct_unchecked().clone_value(), }, 1 => esdt_transfers.get(0).clone(), _ => A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_ESDT_TRANSFERS.as_bytes()), } } + /// Retrieves the EGLD call value and crashes if anything else was transferred. + /// + /// Accepts both EGLD sent directly, as well as EGLD sent alone in a multi-transfer. + /// + /// Does not accept a multi-transfer with 2 or more EGLD transfers. + pub fn single_egld_value(&self) -> ManagedRef<'static, A, BigUint> { + let esdt_transfers_handle = self.all_esdt_transfers_unchecked(); + let esdt_transfers: ManagedRef<'static, A, ManagedVec>> = + unsafe { ManagedRef::wrap_handle(esdt_transfers_handle) }; + match esdt_transfers.len() { + 0 => self.egld_value_direct_unchecked(), + 1 => { + let first = esdt_transfers.get(0); + if !first.token_identifier.is_egld() { + A::error_api_impl().signal_error(err_msg::NON_PAYABLE_FUNC_ESDT.as_bytes()); + } + unsafe { ManagedRef::wrap_handle(first.amount.get_handle()) } + }, + _ => A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_TRANSFERS.as_bytes()), + } + } + /// Accepts and returns either an EGLD payment, or a single fungible ESDT token. /// /// Will halt execution if more than one ESDT transfer was received, or if the received ESDT is non- or semi-fungible. @@ -232,7 +254,7 @@ where pub fn any_payment(&self) -> EgldOrMultiEsdtPayment { let esdt_transfers = self.all_esdt_transfers(); if esdt_transfers.is_empty() { - EgldOrMultiEsdtPayment::Egld(self.egld_value_unchecked().clone_value()) + EgldOrMultiEsdtPayment::Egld(self.egld_value_direct_unchecked().clone_value()) } else { EgldOrMultiEsdtPayment::MultiEsdt(esdt_transfers.clone_value()) } diff --git a/framework/base/src/io/call_value_init.rs b/framework/base/src/io/call_value_init.rs index 93c1bd4f67..c83f6feaa8 100644 --- a/framework/base/src/io/call_value_init.rs +++ b/framework/base/src/io/call_value_init.rs @@ -28,11 +28,10 @@ where /// Called initially in the generated code whenever `#[payable("EGLD")]` annotation is provided. pub fn payable_egld() where - A: CallValueApi + ErrorApi, + A: CallValueApi + ErrorApi + ManagedTypeApi, { - if A::call_value_api_impl().esdt_num_transfers() > 0 { - A::error_api_impl().signal_error(err_msg::NON_PAYABLE_FUNC_ESDT.as_bytes()); - } + // will crash if anything other than (single) EGLD was transferred + let _ = CallValueWrapper::::new().single_egld_value(); } /// Called initially in the generated code whenever `#[payable("")]` annotation is provided. From 17c99c886deedd343d2c20dbcbe8ea7876531161 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 8 Jan 2025 15:23:24 +0200 Subject: [PATCH 130/133] proxy update --- .../composability/forwarder-interactor/src/proxy.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs b/contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs index efa27be50f..649152b06e 100644 --- a/contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs +++ b/contracts/feature-tests/composability/forwarder-interactor/src/proxy.rs @@ -345,7 +345,7 @@ where pub fn send_async_accept_multi_transfer< Arg0: ProxyArg>, - Arg1: ProxyArg, u64, BigUint>>>, + Arg1: ProxyArg, u64, BigUint>>>, >( self, to: Arg0, @@ -445,7 +445,7 @@ where pub fn transf_exec_multi_accept_funds< Arg0: ProxyArg>, - Arg1: ProxyArg, u64, BigUint>>>, + Arg1: ProxyArg, u64, BigUint>>>, >( self, to: Arg0, From 616a983aabf3ad4c6f504f59fb9084fb34fac363 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 8 Jan 2025 16:30:46 +0200 Subject: [PATCH 131/133] call value - egld/egld_direct_non_strict; egld_value deprecated --- contracts/core/wegld-swap/src/wegld.rs | 2 +- .../crypto-bubbles/src/crypto_bubbles.rs | 4 +- .../crypto-kitties/kitty-auction/src/lib.rs | 2 +- .../crypto-kitties/kitty-ownership/src/lib.rs | 2 +- .../crypto-zombies/src/zombie_helper.rs | 2 +- .../digital-cash/src/pay_fee_and_fund.rs | 5 +- .../src/esdt_transfer_with_fee.rs | 2 +- .../fractional-nfts/src/fractional_nfts.rs | 2 +- .../examples/nft-minter/src/nft_module.rs | 2 +- .../src/nft_storage_prepay.rs | 2 +- .../examples/nft-subscription/src/lib.rs | 3 +- .../examples/ping-pong-egld/src/ping_pong.rs | 2 +- .../seed-nft-minter/src/nft_module.rs | 2 +- .../src/storage_mapper_fungible_token.rs | 6 +- .../src/storage_mapper_non_fungible_token.rs | 2 +- .../child/src/lib.rs | 2 +- .../parent/src/lib.rs | 2 +- .../forwarder-legacy/src/fwd_esdt_legacy.rs | 2 +- .../forwarder-legacy/src/fwd_nft_legacy.rs | 2 +- .../forwarder-legacy/src/fwd_sft_legacy.rs | 2 +- .../forwarder-raw/src/forwarder_raw.rs | 25 ++----- .../src/forwarder_raw_alt_init.rs | 2 +- .../forwarder-raw/src/forwarder_raw_async.rs | 2 +- .../forwarder-raw/src/forwarder_raw_sync.rs | 6 +- .../forwarder/src/fwd_call_sync.rs | 2 +- .../composability/forwarder/src/fwd_esdt.rs | 2 +- .../composability/forwarder/src/fwd_nft.rs | 2 +- .../composability/forwarder/src/fwd_sft.rs | 2 +- .../local-esdt-and-nft/src/lib.rs | 6 +- .../proxy-test-first/src/proxy-test-first.rs | 8 +-- .../src/proxy-test-second.rs | 6 +- .../payable-features/src/payable_features.rs | 8 +-- .../rust-testing-framework-tester/src/lib.rs | 4 +- .../tests/use_module_scenario_rs_test.rs | 2 +- .../modules/src/default_issue_callbacks.rs | 4 +- contracts/modules/src/dns.rs | 2 +- contracts/modules/src/esdt.rs | 4 +- .../src/token_merge/merged_token_setup.rs | 2 +- .../wrappers/call_value_wrapper.rs | 69 +++++++++++-------- framework/base/src/io/call_value_init.rs | 2 +- 40 files changed, 108 insertions(+), 102 deletions(-) diff --git a/contracts/core/wegld-swap/src/wegld.rs b/contracts/core/wegld-swap/src/wegld.rs index cb07f2b31a..6223d4647f 100644 --- a/contracts/core/wegld-swap/src/wegld.rs +++ b/contracts/core/wegld-swap/src/wegld.rs @@ -16,7 +16,7 @@ pub trait EgldEsdtSwap: multiversx_sc_modules::pause::PauseModule { fn wrap_egld(&self) -> EsdtTokenPayment { self.require_not_paused(); - let payment_amount = self.call_value().single_egld_value(); + let payment_amount = self.call_value().egld(); require!(*payment_amount > 0u32, "Payment must be more than 0"); let wrapped_egld_token_id = self.wrapped_egld_token_id().get(); diff --git a/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs b/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs index 5c5f791633..8867e6db39 100644 --- a/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs +++ b/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs @@ -13,7 +13,7 @@ pub trait CryptoBubbles { #[payable("EGLD")] #[endpoint(topUp)] fn top_up(&self) { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); let caller = self.blockchain().get_caller(); self.player_balance(&caller) .update(|balance| *balance += &*payment); @@ -63,7 +63,7 @@ pub trait CryptoBubbles { #[payable("EGLD")] #[endpoint(joinGame)] fn join_game(&self, game_index: BigUint) { - let bet = self.call_value().single_egld_value(); + let bet = self.call_value().egld(); let player = self.blockchain().get_caller(); self.top_up(); self.add_player_to_game_state_change(&game_index, &player, &bet) diff --git a/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs b/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs index aadcfe8c8c..f750b1c41c 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs @@ -152,7 +152,7 @@ pub trait KittyAuction { #[payable("EGLD")] #[endpoint] fn bid(&self, kitty_id: u32) { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); require!( self.is_up_for_auction(kitty_id), diff --git a/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs b/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs index b65b2ee5a1..a56382fe54 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs @@ -287,7 +287,7 @@ pub trait KittyOwnership { require!(self.is_valid_id(matron_id), "Invalid matron id!"); require!(self.is_valid_id(sire_id), "Invalid sire id!"); - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); let auto_birth_fee = self.birth_fee().get(); let caller = self.blockchain().get_caller(); diff --git a/contracts/examples/crypto-zombies/src/zombie_helper.rs b/contracts/examples/crypto-zombies/src/zombie_helper.rs index ef0e04793a..cc3786049c 100644 --- a/contracts/examples/crypto-zombies/src/zombie_helper.rs +++ b/contracts/examples/crypto-zombies/src/zombie_helper.rs @@ -19,7 +19,7 @@ pub trait ZombieHelper: storage::Storage { #[payable("EGLD")] #[endpoint] fn level_up(&self, zombie_id: usize) { - let payment_amount = self.call_value().single_egld_value(); + let payment_amount = self.call_value().egld(); let fee = self.level_up_fee().get(); require!(*payment_amount == fee, "Payment must be must be 0.001 EGLD"); self.zombies(&zombie_id) diff --git a/contracts/examples/digital-cash/src/pay_fee_and_fund.rs b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs index 2aaf115996..452c2fa6c8 100644 --- a/contracts/examples/digital-cash/src/pay_fee_and_fund.rs +++ b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs @@ -19,7 +19,7 @@ pub trait PayFeeAndFund: storage::StorageModule + helpers::HelpersModule { #[endpoint(payFeeAndFundEGLD)] #[payable("EGLD")] fn pay_fee_and_fund_egld(&self, address: ManagedAddress, valability: u64) { - let mut fund = self.call_value().single_egld_value().clone_value(); + let mut fund = self.call_value().egld().clone_value(); let fee_value = self.fee(&EgldOrEsdtTokenIdentifier::egld()).get(); require!(fund > fee_value, "payment not covering fees"); @@ -43,7 +43,8 @@ pub trait PayFeeAndFund: storage::StorageModule + helpers::HelpersModule { ); let deposited_fee_token = deposit_mapper.fees.value; let fee_amount = self.fee(&deposited_fee_token.token_identifier).get(); - let egld_payment = self.call_value().egld_value().clone_value(); + // TODO: switch to egld+esdt multi transfer handling + let egld_payment = self.call_value().egld_direct_non_strict().clone_value(); let esdt_payment = self.call_value().all_esdt_transfers().clone_value(); let num_tokens = self.get_num_token_transfers(&egld_payment, &esdt_payment); diff --git a/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs b/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs index b885ec371f..4f21906d89 100644 --- a/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs +++ b/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs @@ -47,7 +47,7 @@ pub trait EsdtTransferWithFee { #[endpoint] fn transfer(&self, address: ManagedAddress) { require!( - *self.call_value().egld_value() == 0, + *self.call_value().egld_direct_non_strict() == 0, "EGLD transfers not allowed" ); let payments = self.call_value().all_esdt_transfers(); diff --git a/contracts/examples/fractional-nfts/src/fractional_nfts.rs b/contracts/examples/fractional-nfts/src/fractional_nfts.rs index fea51e2431..90fd50af41 100644 --- a/contracts/examples/fractional-nfts/src/fractional_nfts.rs +++ b/contracts/examples/fractional-nfts/src/fractional_nfts.rs @@ -20,7 +20,7 @@ pub trait FractionalNfts: default_issue_callbacks::DefaultIssueCallbacksModule { token_ticker: ManagedBuffer, num_decimals: usize, ) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().egld(); self.fractional_token().issue_and_set_all_roles( EsdtTokenType::SemiFungible, issue_cost.clone_value(), diff --git a/contracts/examples/nft-minter/src/nft_module.rs b/contracts/examples/nft-minter/src/nft_module.rs index 6629c22d11..e085f11516 100644 --- a/contracts/examples/nft-minter/src/nft_module.rs +++ b/contracts/examples/nft-minter/src/nft_module.rs @@ -21,7 +21,7 @@ pub trait NftModule { fn issue_token(&self, token_name: ManagedBuffer, token_ticker: ManagedBuffer) { require!(self.nft_token_id().is_empty(), "Token already issued"); - let payment_amount = self.call_value().egld_value(); + let payment_amount = self.call_value().egld(); self.send() .esdt_system_sc_proxy() .issue_non_fungible( diff --git a/contracts/examples/nft-storage-prepay/src/nft_storage_prepay.rs b/contracts/examples/nft-storage-prepay/src/nft_storage_prepay.rs index 7e1c6115d3..e7ec86abea 100644 --- a/contracts/examples/nft-storage-prepay/src/nft_storage_prepay.rs +++ b/contracts/examples/nft-storage-prepay/src/nft_storage_prepay.rs @@ -50,7 +50,7 @@ pub trait NftStoragePrepay { #[payable("EGLD")] #[endpoint(depositPaymentForStorage)] fn deposit_payment_for_storage(&self) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().egld(); let caller = self.blockchain().get_caller(); self.deposit(&caller) .update(|deposit| *deposit += &*payment); diff --git a/contracts/examples/nft-subscription/src/lib.rs b/contracts/examples/nft-subscription/src/lib.rs index beca5ac5bf..0a89597231 100644 --- a/contracts/examples/nft-subscription/src/lib.rs +++ b/contracts/examples/nft-subscription/src/lib.rs @@ -12,10 +12,11 @@ pub trait NftSubscription: fn init(&self) {} #[endpoint] + #[payable("EGLD")] fn issue(&self) { self.token_id().issue_and_set_all_roles( EsdtTokenType::NonFungible, - self.call_value().egld_value().clone_value(), + self.call_value().egld().clone_value(), ManagedBuffer::from(b"Subscription"), ManagedBuffer::from(b"SUB"), 0, diff --git a/contracts/examples/ping-pong-egld/src/ping_pong.rs b/contracts/examples/ping-pong-egld/src/ping_pong.rs index abecb0dbcc..0f44ffdee8 100644 --- a/contracts/examples/ping-pong-egld/src/ping_pong.rs +++ b/contracts/examples/ping-pong-egld/src/ping_pong.rs @@ -69,7 +69,7 @@ pub trait PingPong { #[payable("EGLD")] #[endpoint] fn ping(&self, _data: IgnoreValue) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().egld(); require!( *payment == self.ping_amount().get(), diff --git a/contracts/examples/seed-nft-minter/src/nft_module.rs b/contracts/examples/seed-nft-minter/src/nft_module.rs index 8c271e5686..47628ab55d 100644 --- a/contracts/examples/seed-nft-minter/src/nft_module.rs +++ b/contracts/examples/seed-nft-minter/src/nft_module.rs @@ -25,7 +25,7 @@ pub trait NftModule: #[payable("EGLD")] #[endpoint(issueToken)] fn issue_token(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().egld_value(); + let issue_cost = self.call_value().egld(); self.nft_token_id().issue_and_set_all_roles( EsdtTokenType::NonFungible, issue_cost.clone_value(), diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs b/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs index feeecb2b33..85653e4966 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs @@ -11,7 +11,7 @@ pub trait FungibleTokenMapperFeatures: token_ticker: ManagedBuffer, initial_supply: BigUint, ) { - let payment_amount = self.call_value().egld_value(); + let payment_amount = self.call_value().egld(); self.fungible_token_mapper().issue( payment_amount.clone_value(), ManagedBuffer::new(), @@ -25,7 +25,7 @@ pub trait FungibleTokenMapperFeatures: #[payable("EGLD")] #[endpoint] fn issue_fungible_custom_callback(&self, token_ticker: ManagedBuffer, initial_supply: BigUint) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().egld(); let cb = if initial_supply > 0 { FungibleTokenMapperFeatures::callbacks(self).custom_issue_non_zero_supply_cb() } else { @@ -74,7 +74,7 @@ pub trait FungibleTokenMapperFeatures: #[payable("EGLD")] #[endpoint] fn issue_and_set_all_roles_fungible(&self, token_ticker: ManagedBuffer) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().egld(); self.fungible_token_mapper().issue_and_set_all_roles( payment.clone_value(), ManagedBuffer::new(), diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs b/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs index 4e341f04bd..531ec0da7a 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs @@ -16,7 +16,7 @@ pub trait NonFungibleTokenMapperFeatures: #[payable("EGLD")] #[endpoint] fn issue_and_set_all_roles_meta(&self, token_ticker: ManagedBuffer) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().egld(); self.non_fungible_token_mapper().issue_and_set_all_roles( EsdtTokenType::Meta, payment.clone_value(), diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs index d5ff191862..acc593e885 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs @@ -17,7 +17,7 @@ pub trait Child { token_ticker: ManagedBuffer, initial_supply: BigUint, ) { - let issue_cost = self.call_value().single_egld_value(); + let issue_cost = self.call_value().egld(); self.send() .esdt_system_sc_proxy() .issue_fungible( diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs index 139a58673c..8ee7f26c69 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs @@ -38,7 +38,7 @@ pub trait Parent { token_ticker: ManagedBuffer, initial_supply: BigUint, ) { - let issue_cost = self.call_value().single_egld_value(); + let issue_cost = self.call_value().egld(); let child_contract_adress = self.child_contract_address().get(); self.tx() diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs index 871d0e5f70..84782829cd 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs @@ -90,7 +90,7 @@ pub trait ForwarderEsdtModule: fwd_storage_legacy::ForwarderStorageModule { token_ticker: ManagedBuffer, initial_supply: BigUint, ) { - let issue_cost = self.call_value().single_egld_value(); + let issue_cost = self.call_value().egld(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs index 0b8477c3d9..c62ae0154c 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs @@ -52,7 +52,7 @@ pub trait ForwarderNftModule: fwd_storage_legacy::ForwarderStorageModule { #[payable("EGLD")] #[endpoint] fn nft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().single_egld_value(); + let issue_cost = self.call_value().egld(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs index f320663e29..9629c73534 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs @@ -7,7 +7,7 @@ pub trait ForwarderSftModule: fwd_storage_legacy::ForwarderStorageModule { #[payable("EGLD")] #[endpoint] fn sft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().single_egld_value(); + let issue_cost = self.call_value().egld(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs index 796bea5684..810cddba5e 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw.rs @@ -24,24 +24,13 @@ pub trait ForwarderRaw: #[callback_raw] fn callback_raw(&self, args: MultiValueEncoded) { - let payments = self.call_value().all_esdt_transfers(); - if payments.is_empty() { - let egld_value = self.call_value().egld_value(); - if *egld_value > 0 { - let _ = self.callback_payments().push(&( - EgldOrEsdtTokenIdentifier::egld(), - 0, - egld_value.clone_value(), - )); - } - } else { - for payment in payments.iter() { - let _ = self.callback_payments().push(&( - EgldOrEsdtTokenIdentifier::esdt(payment.token_identifier.clone()), - payment.token_nonce, - payment.amount.clone(), - )); - } + let payments = self.call_value().all_transfers(); + for payment in payments.iter() { + let _ = self.callback_payments().push(&( + payment.token_identifier.clone(), + payment.token_nonce, + payment.amount.clone(), + )); } let args_as_vec = args.into_vec_of_buffers(); diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs index 97f7e8cd11..e0b6058bcd 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs @@ -52,7 +52,7 @@ pub trait ForwarderRawAlterativeInit: super::forwarder_raw_common::ForwarderRawC endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); let half_gas = self.blockchain().get_gas_left() / 2; let result = self 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 a8e421982a..713baf996d 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 @@ -91,7 +91,7 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); self.forward_contract_call( to, EgldOrEsdtTokenIdentifier::egld(), diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs index ea453ecf9f..7be0a34118 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs @@ -10,7 +10,7 @@ pub trait ForwarderRawSync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().single_egld_value().clone_value(); + let payment = self.call_value().egld().clone_value(); let half_gas = self.blockchain().get_gas_left() / 2; let result = self .tx() @@ -33,7 +33,7 @@ pub trait ForwarderRawSync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); let one_third_gas = self.blockchain().get_gas_left() / 3; let half_payment = &*payment / 2u32; let arg_buffer = args.to_arg_buffer(); @@ -71,7 +71,7 @@ pub trait ForwarderRawSync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); let half_gas = self.blockchain().get_gas_left() / 2; let result = self 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 8b9a30a6be..2ad4f1171e 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs @@ -80,7 +80,7 @@ pub trait ForwarderSyncCallModule { #[endpoint] #[payable("EGLD")] fn forward_sync_accept_funds_rh_egld(&self, to: ManagedAddress) -> BigUint { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); let half_gas = self.blockchain().get_gas_left() / 2; self.tx() diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs b/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs index 7f289e10db..a5e76927d7 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs @@ -95,7 +95,7 @@ pub trait ForwarderEsdtModule: fwd_storage::ForwarderStorageModule { token_ticker: ManagedBuffer, initial_supply: BigUint, ) { - let issue_cost = self.call_value().single_egld_value(); + let issue_cost = self.call_value().egld(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs b/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs index dc9400a269..6f2e9f0ae6 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs @@ -52,7 +52,7 @@ pub trait ForwarderNftModule: fwd_storage::ForwarderStorageModule { #[payable("EGLD")] #[endpoint] fn nft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().single_egld_value(); + let issue_cost = self.call_value().egld(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs b/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs index 832e424527..6ea5ee917e 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs @@ -7,7 +7,7 @@ pub trait ForwarderSftModule: fwd_storage::ForwarderStorageModule { #[payable("EGLD")] #[endpoint] fn sft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().single_egld_value(); + let issue_cost = self.call_value().egld(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs b/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs index 311f98c48b..ec7e8a3197 100644 --- a/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs +++ b/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs @@ -27,7 +27,7 @@ pub trait LocalEsdtAndEsdtNft { token_ticker: ManagedBuffer, initial_supply: BigUint, ) { - let issue_cost = self.call_value().single_egld_value(); + let issue_cost = self.call_value().egld(); let caller = self.blockchain().get_caller(); self.send() @@ -68,7 +68,7 @@ pub trait LocalEsdtAndEsdtNft { #[payable("EGLD")] #[endpoint(nftIssue)] fn nft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().single_egld_value(); + let issue_cost = self.call_value().egld(); let caller = self.blockchain().get_caller(); self.send() @@ -174,7 +174,7 @@ pub trait LocalEsdtAndEsdtNft { #[payable("EGLD")] #[endpoint(sftIssue)] fn sft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let issue_cost = self.call_value().single_egld_value(); + let issue_cost = self.call_value().egld(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs b/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs index 7e355d0fe4..718ecf4a61 100644 --- a/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs +++ b/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs @@ -29,7 +29,7 @@ pub trait ProxyTestFirst { #[payable("EGLD")] #[endpoint(deploySecondContract)] fn deploy_second_contract(&self, code: ManagedBuffer) -> i32 { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); let (address, init_result) = self .tx() @@ -49,7 +49,7 @@ pub trait ProxyTestFirst { #[payable("EGLD")] #[endpoint(upgradeSecondContract)] fn upgrade_second_contract(&self, code: ManagedBuffer) { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); let other_contract = self.get_other_contract(); self.tx() @@ -66,7 +66,7 @@ pub trait ProxyTestFirst { #[payable("EGLD")] #[endpoint(forwardToOtherContract)] fn forward_to_other_contract(&self) { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); let other_contract = self.get_other_contract(); self.tx() .to(&other_contract) @@ -79,7 +79,7 @@ pub trait ProxyTestFirst { #[payable("EGLD")] #[endpoint(forwardToOtherContractWithCallback)] fn forward_to_other_contract_with_callback(&self) { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); let other_contract = self.get_other_contract(); self.tx() .to(&other_contract) diff --git a/contracts/feature-tests/composability/proxy-test-second/src/proxy-test-second.rs b/contracts/feature-tests/composability/proxy-test-second/src/proxy-test-second.rs index f4b0108a48..5f0d249f89 100644 --- a/contracts/feature-tests/composability/proxy-test-second/src/proxy-test-second.rs +++ b/contracts/feature-tests/composability/proxy-test-second/src/proxy-test-second.rs @@ -28,7 +28,7 @@ pub trait ProxyTestSecond { #[init] #[payable("EGLD")] fn init(&self, init_arg: i32) -> i32 { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); self.set_last_payment(&payment); self.set_init_arg(init_arg); init_arg + 1 @@ -43,7 +43,7 @@ pub trait ProxyTestSecond { #[payable("EGLD")] #[endpoint(payMe)] fn pay_me(&self, arg1: i64) { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); self.set_last_payment(&payment); self.set_pay_me_arg(arg1); } @@ -51,7 +51,7 @@ pub trait ProxyTestSecond { #[payable("EGLD")] #[endpoint(payMeWithResult)] fn pay_me_with_result_endpoint(&self, arg1: i64) -> i64 { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); self.set_last_payment(&payment); self.set_pay_me_arg(arg1); diff --git a/contracts/feature-tests/payable-features/src/payable_features.rs b/contracts/feature-tests/payable-features/src/payable_features.rs index 7559b21f54..5b0f18f39b 100644 --- a/contracts/feature-tests/payable-features/src/payable_features.rs +++ b/contracts/feature-tests/payable-features/src/payable_features.rs @@ -16,7 +16,7 @@ pub trait PayableFeatures { #[payable("*")] fn echo_call_value_legacy(&self) -> MultiValue2> { ( - self.call_value().egld_value().clone_value(), + self.call_value().egld_direct_non_strict().clone_value(), self.call_value().all_esdt_transfers().clone_value(), ) .into() @@ -104,7 +104,7 @@ pub trait PayableFeatures { &self, #[payment_token] token: EgldOrEsdtTokenIdentifier, ) -> MultiValue2 { - let payment = self.call_value().single_egld_value().clone_value(); + let payment = self.call_value().egld().clone_value(); (payment, token).into() } @@ -124,14 +124,14 @@ pub trait PayableFeatures { &self, #[payment_token] token: EgldOrEsdtTokenIdentifier, ) -> MultiValue2 { - let payment = self.call_value().single_egld_value().clone_value(); + let payment = self.call_value().egld().clone_value(); (payment, token).into() } #[endpoint] #[payable("EGLD")] fn payable_egld_4(&self) -> MultiValue2 { - let payment = self.call_value().single_egld_value(); + let payment = self.call_value().egld(); let token = self.call_value().egld_or_single_esdt().token_identifier; (payment.clone_value(), token).into() } diff --git a/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs b/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs index c62cce964c..4c77692fb3 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs @@ -57,13 +57,13 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[payable("EGLD")] #[endpoint] fn receive_egld(&self) -> BigUint { - self.call_value().single_egld_value().clone_value() + self.call_value().egld().clone_value() } #[payable("EGLD")] #[endpoint] fn recieve_egld_half(&self) { - let payment_amount = &*self.call_value().single_egld_value() / 2u32; + let payment_amount = &*self.call_value().egld() / 2u32; self.tx().to(ToCaller).egld(payment_amount).transfer(); } diff --git a/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs b/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs index 5e68116633..27e698c153 100644 --- a/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs +++ b/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs @@ -6,7 +6,7 @@ mod dns_mock { #[payable("EGLD")] #[endpoint] fn register(&self, name: BoxedBytes) { - let _payment = self.call_value().single_egld_value(); + let _payment = self.call_value().egld(); let address = self.blockchain().get_caller(); self.tx() .to(&address) diff --git a/contracts/modules/src/default_issue_callbacks.rs b/contracts/modules/src/default_issue_callbacks.rs index 8e9e1c6e90..036ac2da0d 100644 --- a/contracts/modules/src/default_issue_callbacks.rs +++ b/contracts/modules/src/default_issue_callbacks.rs @@ -46,8 +46,8 @@ pub trait DefaultIssueCallbacksModule { } fn return_failed_issue_funds(&self, initial_caller: ManagedAddress) { - let egld_returned = self.call_value().egld_value().to_u64().unwrap(); - if egld_returned > 0u64 { + let egld_returned = self.call_value().egld_direct_non_strict(); + if *egld_returned > 0u64 { self.tx().to(&initial_caller).egld(egld_returned).transfer(); } } diff --git a/contracts/modules/src/dns.rs b/contracts/modules/src/dns.rs index 20cf5e63fe..782e0ad0b1 100644 --- a/contracts/modules/src/dns.rs +++ b/contracts/modules/src/dns.rs @@ -13,7 +13,7 @@ pub trait DnsModule { #[only_owner] #[endpoint(dnsRegister)] fn dns_register(&self, dns_address: ManagedAddress, name: ManagedBuffer) { - let payment = self.call_value().single_egld_value().clone_value(); + let payment = self.call_value().egld().clone_value(); self.tx() .to(&dns_address) .typed(dns_proxy::DnsProxy) diff --git a/contracts/modules/src/esdt.rs b/contracts/modules/src/esdt.rs index e38307c450..a6aed9239e 100644 --- a/contracts/modules/src/esdt.rs +++ b/contracts/modules/src/esdt.rs @@ -34,7 +34,7 @@ pub trait EsdtModule { ) { require!(self.token_id().is_empty(), "Token already issued"); - let issue_cost = self.call_value().single_egld_value().clone_value(); + let issue_cost = self.call_value().egld().clone_value(); let num_decimals = match opt_num_decimals { OptionalValue::Some(d) => d, OptionalValue::None => 0, @@ -62,7 +62,7 @@ pub trait EsdtModule { ManagedAsyncCallResult::Err(_) => { // return payment to initial caller let initial_caller = self.blockchain().get_owner_address(); - let egld_returned = self.call_value().egld_value(); + let egld_returned = self.call_value().egld(); self.tx() .to(&initial_caller) .egld(egld_returned) diff --git a/contracts/modules/src/token_merge/merged_token_setup.rs b/contracts/modules/src/token_merge/merged_token_setup.rs index 309c924ddb..58bead8c9d 100644 --- a/contracts/modules/src/token_merge/merged_token_setup.rs +++ b/contracts/modules/src/token_merge/merged_token_setup.rs @@ -14,7 +14,7 @@ pub trait MergedTokenSetupModule { #[payable("EGLD")] #[endpoint(issueMergedToken)] fn issue_merged_token(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { - let payment_amount = self.call_value().single_egld_value(); + let payment_amount = self.call_value().egld(); self.merged_token().issue_and_set_all_roles( EsdtTokenType::NonFungible, payment_amount.clone_value(), diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 65e49b34f9..c6b2650781 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -47,7 +47,10 @@ where all_transfers_unchecked_handle } - fn egld_value_direct_unchecked(&self) -> ManagedRef<'static, A, BigUint> { + /// Retrieves the EGLD call value from the VM. + /// + /// Will return 0 in case of an ESDT transfer, even though EGLD and ESDT transfers are now posible. + pub fn egld_direct_non_strict(&self) -> ManagedRef<'static, A, BigUint> { let call_value_handle: A::BigIntHandle = use_raw_handle(const_handles::CALL_VALUE_EGLD); if !A::static_var_api_impl() .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_DIRECT_INITIALIZED) @@ -57,11 +60,45 @@ where unsafe { ManagedRef::wrap_handle(call_value_handle) } } + /// Retrieves the EGLD call value and crashes if anything else was transferred. + /// + /// Accepts both EGLD sent directly, as well as EGLD sent alone in a multi-transfer. + /// + /// Does not accept a multi-transfer with 2 or more transfers, not even 2 or more EGLD transfers. + pub fn egld(&self) -> ManagedRef<'static, A, BigUint> { + let esdt_transfers_handle = self.all_esdt_transfers_unchecked(); + let esdt_transfers: ManagedRef<'static, A, ManagedVec>> = + unsafe { ManagedRef::wrap_handle(esdt_transfers_handle) }; + match esdt_transfers.len() { + 0 => self.egld_direct_non_strict(), + 1 => { + let first = esdt_transfers.get(0); + if !first.token_identifier.is_egld() { + A::error_api_impl().signal_error(err_msg::NON_PAYABLE_FUNC_ESDT.as_bytes()); + } + unsafe { ManagedRef::wrap_handle(first.amount.get_handle()) } + }, + _ => A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_TRANSFERS.as_bytes()), + } + } + /// Retrieves the EGLD call value from the VM. /// /// Will return 0 in case of an ESDT transfer, even though EGLD and ESDT transfers are now posible. + /// + /// ## Important! + /// + /// Does not cover multi-transfer scenarios properly, but left for backwards compatibility. + /// + /// Please use `.egld()` instead! + /// + /// For raw handling, `.egld_direct_non_strict()` is also acceptable. + #[deprecated( + since = "0.55.0", + note = "Does not cover multi-transfer scenarios properly, but left for backwards compatibility. Please use .egld() instead!" + )] pub fn egld_value(&self) -> ManagedRef<'static, A, BigUint> { - self.egld_value_direct_unchecked() + self.egld_direct_non_strict() } /// Returns the EGLD call value from the VM as ManagedDecimal @@ -100,7 +137,7 @@ where if !A::static_var_api_impl() .flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED) { - let egld_single = self.egld_value_direct_unchecked(); + let egld_single = self.egld_direct_non_strict(); if bi_gt_zero::(egld_single.get_handle()) { A::managed_type_impl().mb_overwrite( use_raw_handle(const_handles::MBUF_EGLD_000000), @@ -202,35 +239,13 @@ where 0 => EgldOrEsdtTokenPayment { token_identifier: EgldOrEsdtTokenIdentifier::egld(), token_nonce: 0, - amount: self.egld_value_direct_unchecked().clone_value(), + amount: self.egld_direct_non_strict().clone_value(), }, 1 => esdt_transfers.get(0).clone(), _ => A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_ESDT_TRANSFERS.as_bytes()), } } - /// Retrieves the EGLD call value and crashes if anything else was transferred. - /// - /// Accepts both EGLD sent directly, as well as EGLD sent alone in a multi-transfer. - /// - /// Does not accept a multi-transfer with 2 or more EGLD transfers. - pub fn single_egld_value(&self) -> ManagedRef<'static, A, BigUint> { - let esdt_transfers_handle = self.all_esdt_transfers_unchecked(); - let esdt_transfers: ManagedRef<'static, A, ManagedVec>> = - unsafe { ManagedRef::wrap_handle(esdt_transfers_handle) }; - match esdt_transfers.len() { - 0 => self.egld_value_direct_unchecked(), - 1 => { - let first = esdt_transfers.get(0); - if !first.token_identifier.is_egld() { - A::error_api_impl().signal_error(err_msg::NON_PAYABLE_FUNC_ESDT.as_bytes()); - } - unsafe { ManagedRef::wrap_handle(first.amount.get_handle()) } - }, - _ => A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_TRANSFERS.as_bytes()), - } - } - /// Accepts and returns either an EGLD payment, or a single fungible ESDT token. /// /// Will halt execution if more than one ESDT transfer was received, or if the received ESDT is non- or semi-fungible. @@ -254,7 +269,7 @@ where pub fn any_payment(&self) -> EgldOrMultiEsdtPayment { let esdt_transfers = self.all_esdt_transfers(); if esdt_transfers.is_empty() { - EgldOrMultiEsdtPayment::Egld(self.egld_value_direct_unchecked().clone_value()) + EgldOrMultiEsdtPayment::Egld(self.egld_direct_non_strict().clone_value()) } else { EgldOrMultiEsdtPayment::MultiEsdt(esdt_transfers.clone_value()) } diff --git a/framework/base/src/io/call_value_init.rs b/framework/base/src/io/call_value_init.rs index c83f6feaa8..81a79b7cd7 100644 --- a/framework/base/src/io/call_value_init.rs +++ b/framework/base/src/io/call_value_init.rs @@ -31,7 +31,7 @@ where A: CallValueApi + ErrorApi + ManagedTypeApi, { // will crash if anything other than (single) EGLD was transferred - let _ = CallValueWrapper::::new().single_egld_value(); + let _ = CallValueWrapper::::new().egld(); } /// Called initially in the generated code whenever `#[payable("")]` annotation is provided. From 4715c1d46ea5738a66a3bc2d4777b1d412fbbe92 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 8 Jan 2025 21:40:40 +0200 Subject: [PATCH 132/133] call value - fix after merge --- Cargo.lock | 66 +++++++++---------- .../forwarder/src/fwd_dynamic.rs | 4 +- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b428f03b5..aeef450add 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -486,9 +486,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.23" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +checksum = "9560b07a799281c7e0958b9296854d6fafd4c5f31444a7e5bb1ad6dde5ccf1bd" dependencies = [ "clap_builder", "clap_derive", @@ -496,9 +496,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.23" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +checksum = "874e0dd3eb68bf99058751ac9712f622e61e6f393a94f7128fa26e3f02f5c7cd" dependencies = [ "anstream", "anstyle", @@ -508,9 +508,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" dependencies = [ "heck", "proc-macro2", @@ -2206,9 +2206,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" @@ -3038,18 +3038,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" dependencies = [ "proc-macro2", "quote", @@ -3058,9 +3058,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -3622,9 +3622,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.42" +version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ "bitflags", "errno", @@ -3793,9 +3793,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -3873,9 +3873,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.134" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ "indexmap 2.7.0", "itoa", @@ -4261,9 +4261,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.42.0" +version = "1.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", "bytes", @@ -4279,9 +4279,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", @@ -4689,12 +4689,12 @@ checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wasm-encoder" -version = "0.222.0" +version = "0.223.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3432682105d7e994565ef928ccf5856cf6af4ba3dddebedb737f61caed70f956" +checksum = "7e636076193fa68103e937ac951b5f2f587624097017d764b8984d9c0f149464" dependencies = [ "leb128", - "wasmparser 0.222.0", + "wasmparser 0.223.0", ] [[package]] @@ -4713,9 +4713,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.222.0" +version = "0.223.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4adf50fde1b1a49c1add6a80d47aea500c88db70551805853aa8b88f3ea27ab5" +checksum = "d5a99faceb1a5a84dd6084ec4bfa4b2ab153b5793b43fd8f58b89232634afc35" dependencies = [ "bitflags", "indexmap 2.7.0", @@ -4735,9 +4735,9 @@ dependencies = [ [[package]] name = "wast" -version = "222.0.0" +version = "223.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce7191f4b7da0dd300cc32476abae6457154e4625d9b1bc26890828a9a26f6e" +checksum = "d59b2ba8a2ff9f06194b7be9524f92e45e70149f4dacc0d0c7ad92b59ac875e4" dependencies = [ "bumpalo", "leb128", @@ -4748,9 +4748,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.222.0" +version = "1.223.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fde61b4b52f9a84ae31b5e8902a2cd3162ea45d8bf564c729c3288fe52f4334" +checksum = "662786915c427e4918ff01eabb3c4756d4d947cd8f635761526b4cc9da2eaaad" dependencies = [ "wast", ] diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs b/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs index 14549d99ad..595955e1fd 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs @@ -15,7 +15,7 @@ pub trait ForwarderDynamicModule: token_type: EsdtTokenType, num_decimals: usize, ) { - let issue_cost = self.call_value().egld_value().clone_value(); + let issue_cost = self.call_value().egld().clone_value(); let caller = self.blockchain().get_caller(); self.send() @@ -40,7 +40,7 @@ pub trait ForwarderDynamicModule: token_type: EsdtTokenType, num_decimals: usize, ) { - let issue_cost = self.call_value().egld_value().clone_value(); + let issue_cost = self.call_value().egld().clone_value(); let caller = self.blockchain().get_caller(); self.send() From 64afe64f98e748175282cb2804d58d7e730cabea Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 8 Jan 2025 21:48:56 +0200 Subject: [PATCH 133/133] replaced `clone_value` with `clone` in examples --- contracts/core/wegld-swap/src/wegld.rs | 2 +- .../examples/crypto-kitties/kitty-auction/src/lib.rs | 2 +- .../examples/digital-cash/src/pay_fee_and_fund.rs | 6 +++--- .../examples/fractional-nfts/src/fractional_nfts.rs | 2 +- contracts/examples/nft-minter/src/nft_module.rs | 2 +- contracts/examples/nft-subscription/src/lib.rs | 2 +- contracts/examples/seed-nft-minter/src/nft_module.rs | 2 +- .../src/storage_mapper_fungible_token.rs | 6 +++--- .../src/storage_mapper_non_fungible_token.rs | 2 +- .../child/src/lib.rs | 2 +- .../forwarder-legacy/src/fwd_call_sync_legacy.rs | 2 +- .../forwarder-legacy/src/fwd_esdt_legacy.rs | 2 +- .../forwarder-legacy/src/fwd_nft_legacy.rs | 2 +- .../forwarder-legacy/src/fwd_sft_legacy.rs | 2 +- .../forwarder-raw/src/forwarder_raw_async.rs | 2 +- .../forwarder-raw/src/forwarder_raw_sync.rs | 2 +- .../composability/forwarder/src/fwd_call_sync.rs | 2 +- .../composability/forwarder/src/fwd_dynamic.rs | 4 ++-- .../composability/forwarder/src/fwd_esdt.rs | 2 +- .../composability/forwarder/src/fwd_nft.rs | 2 +- .../composability/forwarder/src/fwd_sft.rs | 2 +- .../composability/local-esdt-and-nft/src/lib.rs | 6 +++--- .../feature-tests/composability/vault/src/vault.rs | 5 +---- .../payable-features/src/payable_features.rs | 10 +++++----- .../rust-testing-framework-tester/src/lib.rs | 4 ++-- contracts/modules/src/dns.rs | 2 +- contracts/modules/src/esdt.rs | 2 +- .../modules/src/token_merge/merged_token_setup.rs | 2 +- .../src/contract_base/wrappers/call_value_wrapper.rs | 10 ++++------ 29 files changed, 44 insertions(+), 49 deletions(-) diff --git a/contracts/core/wegld-swap/src/wegld.rs b/contracts/core/wegld-swap/src/wegld.rs index 6223d4647f..36c2d0fe37 100644 --- a/contracts/core/wegld-swap/src/wegld.rs +++ b/contracts/core/wegld-swap/src/wegld.rs @@ -28,7 +28,7 @@ pub trait EgldEsdtSwap: multiversx_sc_modules::pause::PauseModule { .single_esdt(&wrapped_egld_token_id, 0, &payment_amount) .transfer(); - EsdtTokenPayment::new(wrapped_egld_token_id, 0, payment_amount.clone_value()) + EsdtTokenPayment::new(wrapped_egld_token_id, 0, payment_amount.clone()) } #[payable("*")] diff --git a/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs b/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs index f750b1c41c..39f4841f8b 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs @@ -192,7 +192,7 @@ pub trait KittyAuction { } // update auction bid and winner - auction.current_bid = payment.clone_value(); + auction.current_bid = payment.clone(); auction.current_winner = caller; self.auction(kitty_id).set(auction); } diff --git a/contracts/examples/digital-cash/src/pay_fee_and_fund.rs b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs index 452c2fa6c8..514bbb8e74 100644 --- a/contracts/examples/digital-cash/src/pay_fee_and_fund.rs +++ b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs @@ -19,7 +19,7 @@ pub trait PayFeeAndFund: storage::StorageModule + helpers::HelpersModule { #[endpoint(payFeeAndFundEGLD)] #[payable("EGLD")] fn pay_fee_and_fund_egld(&self, address: ManagedAddress, valability: u64) { - let mut fund = self.call_value().egld().clone_value(); + let mut fund = self.call_value().egld().clone(); let fee_value = self.fee(&EgldOrEsdtTokenIdentifier::egld()).get(); require!(fund > fee_value, "payment not covering fees"); @@ -44,8 +44,8 @@ pub trait PayFeeAndFund: storage::StorageModule + helpers::HelpersModule { let deposited_fee_token = deposit_mapper.fees.value; let fee_amount = self.fee(&deposited_fee_token.token_identifier).get(); // TODO: switch to egld+esdt multi transfer handling - let egld_payment = self.call_value().egld_direct_non_strict().clone_value(); - let esdt_payment = self.call_value().all_esdt_transfers().clone_value(); + let egld_payment = self.call_value().egld_direct_non_strict().clone(); + let esdt_payment = self.call_value().all_esdt_transfers().clone(); let num_tokens = self.get_num_token_transfers(&egld_payment, &esdt_payment); self.check_fees_cover_number_of_tokens(num_tokens, fee_amount, deposited_fee_token.amount); diff --git a/contracts/examples/fractional-nfts/src/fractional_nfts.rs b/contracts/examples/fractional-nfts/src/fractional_nfts.rs index 90fd50af41..007ecffc39 100644 --- a/contracts/examples/fractional-nfts/src/fractional_nfts.rs +++ b/contracts/examples/fractional-nfts/src/fractional_nfts.rs @@ -23,7 +23,7 @@ pub trait FractionalNfts: default_issue_callbacks::DefaultIssueCallbacksModule { let issue_cost = self.call_value().egld(); self.fractional_token().issue_and_set_all_roles( EsdtTokenType::SemiFungible, - issue_cost.clone_value(), + issue_cost.clone(), token_display_name, token_ticker, num_decimals, diff --git a/contracts/examples/nft-minter/src/nft_module.rs b/contracts/examples/nft-minter/src/nft_module.rs index e085f11516..8f503014da 100644 --- a/contracts/examples/nft-minter/src/nft_module.rs +++ b/contracts/examples/nft-minter/src/nft_module.rs @@ -25,7 +25,7 @@ pub trait NftModule { self.send() .esdt_system_sc_proxy() .issue_non_fungible( - payment_amount.clone_value(), + payment_amount.clone(), &token_name, &token_ticker, NonFungibleTokenProperties { diff --git a/contracts/examples/nft-subscription/src/lib.rs b/contracts/examples/nft-subscription/src/lib.rs index 0a89597231..f64140a6b7 100644 --- a/contracts/examples/nft-subscription/src/lib.rs +++ b/contracts/examples/nft-subscription/src/lib.rs @@ -16,7 +16,7 @@ pub trait NftSubscription: fn issue(&self) { self.token_id().issue_and_set_all_roles( EsdtTokenType::NonFungible, - self.call_value().egld().clone_value(), + self.call_value().egld().clone(), ManagedBuffer::from(b"Subscription"), ManagedBuffer::from(b"SUB"), 0, diff --git a/contracts/examples/seed-nft-minter/src/nft_module.rs b/contracts/examples/seed-nft-minter/src/nft_module.rs index 47628ab55d..6d11532fe0 100644 --- a/contracts/examples/seed-nft-minter/src/nft_module.rs +++ b/contracts/examples/seed-nft-minter/src/nft_module.rs @@ -28,7 +28,7 @@ pub trait NftModule: let issue_cost = self.call_value().egld(); self.nft_token_id().issue_and_set_all_roles( EsdtTokenType::NonFungible, - issue_cost.clone_value(), + issue_cost.clone(), token_display_name, token_ticker, 0, diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs b/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs index 85653e4966..203dd28c64 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_fungible_token.rs @@ -13,7 +13,7 @@ pub trait FungibleTokenMapperFeatures: ) { let payment_amount = self.call_value().egld(); self.fungible_token_mapper().issue( - payment_amount.clone_value(), + payment_amount.clone(), ManagedBuffer::new(), token_ticker, initial_supply, @@ -33,7 +33,7 @@ pub trait FungibleTokenMapperFeatures: }; self.fungible_token_mapper().issue( - payment.clone_value(), + payment.clone(), ManagedBuffer::new(), token_ticker, initial_supply, @@ -76,7 +76,7 @@ pub trait FungibleTokenMapperFeatures: fn issue_and_set_all_roles_fungible(&self, token_ticker: ManagedBuffer) { let payment = self.call_value().egld(); self.fungible_token_mapper().issue_and_set_all_roles( - payment.clone_value(), + payment.clone(), ManagedBuffer::new(), token_ticker, 0, diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs b/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs index 531ec0da7a..5a19517b01 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs @@ -19,7 +19,7 @@ pub trait NonFungibleTokenMapperFeatures: let payment = self.call_value().egld(); self.non_fungible_token_mapper().issue_and_set_all_roles( EsdtTokenType::Meta, - payment.clone_value(), + payment.clone(), ManagedBuffer::new(), token_ticker, 0, diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs index acc593e885..dc732e82f9 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs @@ -21,7 +21,7 @@ pub trait Child { self.send() .esdt_system_sc_proxy() .issue_fungible( - issue_cost.clone_value(), + issue_cost.clone(), &token_display_name, &token_ticker, &initial_supply, diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_sync_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_sync_legacy.rs index 67d923936e..53a12a0a1a 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_sync_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_sync_legacy.rs @@ -141,7 +141,7 @@ pub trait ForwarderSyncCallModule { amount, OptionalValue::::Some(b"accept_funds_func".into()), ) - .with_multi_token_transfer(payments.clone_value()) + .with_multi_token_transfer(payments.clone()) .execute_on_dest_context::<()>(); } diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs index 84782829cd..ace0684bab 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs @@ -96,7 +96,7 @@ pub trait ForwarderEsdtModule: fwd_storage_legacy::ForwarderStorageModule { self.send() .esdt_system_sc_proxy() .issue_fungible( - issue_cost.clone_value(), + issue_cost.clone(), &token_display_name, &token_ticker, &initial_supply, diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs index c62ae0154c..1c18fb556a 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs @@ -58,7 +58,7 @@ pub trait ForwarderNftModule: fwd_storage_legacy::ForwarderStorageModule { self.send() .esdt_system_sc_proxy() .issue_non_fungible( - issue_cost.clone_value(), + issue_cost.clone(), &token_display_name, &token_ticker, NonFungibleTokenProperties { diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs index 9629c73534..a2b1b583af 100644 --- a/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs @@ -13,7 +13,7 @@ pub trait ForwarderSftModule: fwd_storage_legacy::ForwarderStorageModule { self.send() .esdt_system_sc_proxy() .issue_semi_fungible( - issue_cost.clone_value(), + issue_cost.clone(), &token_display_name, &token_ticker, SemiFungibleTokenProperties { 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 713baf996d..0af2c870e4 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 @@ -95,7 +95,7 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { self.forward_contract_call( to, EgldOrEsdtTokenIdentifier::egld(), - payment.clone_value(), + payment.clone(), endpoint_name, args, ) diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs index 7be0a34118..bd1188c1bb 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs @@ -10,7 +10,7 @@ pub trait ForwarderRawSync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().egld().clone_value(); + let payment = self.call_value().egld().clone(); let half_gas = self.blockchain().get_gas_left() / 2; let result = 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 2ad4f1171e..0a8602ee33 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs @@ -125,7 +125,7 @@ pub trait ForwarderSyncCallModule { &self, to: ManagedAddress, ) -> ManagedVec> { - let payment = self.call_value().all_esdt_transfers().clone_value(); + let payment = self.call_value().all_esdt_transfers().clone(); let half_gas = self.blockchain().get_gas_left() / 2; self.tx() diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs b/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs index 595955e1fd..8fd139d485 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_dynamic.rs @@ -15,7 +15,7 @@ pub trait ForwarderDynamicModule: token_type: EsdtTokenType, num_decimals: usize, ) { - let issue_cost = self.call_value().egld().clone_value(); + let issue_cost = self.call_value().egld().clone(); let caller = self.blockchain().get_caller(); self.send() @@ -40,7 +40,7 @@ pub trait ForwarderDynamicModule: token_type: EsdtTokenType, num_decimals: usize, ) { - let issue_cost = self.call_value().egld().clone_value(); + let issue_cost = self.call_value().egld().clone(); let caller = self.blockchain().get_caller(); self.send() diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs b/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs index a5e76927d7..e66f697f88 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs @@ -101,7 +101,7 @@ pub trait ForwarderEsdtModule: fwd_storage::ForwarderStorageModule { self.send() .esdt_system_sc_proxy() .issue_fungible( - issue_cost.clone_value(), + issue_cost.clone(), &token_display_name, &token_ticker, &initial_supply, diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs b/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs index cc7f59a91a..883851f178 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs @@ -58,7 +58,7 @@ pub trait ForwarderNftModule: fwd_storage::ForwarderStorageModule { self.send() .esdt_system_sc_proxy() .issue_non_fungible( - issue_cost.clone_value(), + issue_cost.clone(), &token_display_name, &token_ticker, NonFungibleTokenProperties { diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs b/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs index 6ea5ee917e..657608f17b 100644 --- a/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs +++ b/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs @@ -13,7 +13,7 @@ pub trait ForwarderSftModule: fwd_storage::ForwarderStorageModule { self.send() .esdt_system_sc_proxy() .issue_semi_fungible( - issue_cost.clone_value(), + issue_cost.clone(), &token_display_name, &token_ticker, SemiFungibleTokenProperties { diff --git a/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs b/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs index ec7e8a3197..457c76b722 100644 --- a/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs +++ b/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs @@ -33,7 +33,7 @@ pub trait LocalEsdtAndEsdtNft { self.send() .esdt_system_sc_proxy() .issue_fungible( - issue_cost.clone_value(), + issue_cost.clone(), &token_display_name, &token_ticker, &initial_supply, @@ -74,7 +74,7 @@ pub trait LocalEsdtAndEsdtNft { self.send() .esdt_system_sc_proxy() .issue_non_fungible( - issue_cost.clone_value(), + issue_cost.clone(), &token_display_name, &token_ticker, NonFungibleTokenProperties { @@ -180,7 +180,7 @@ pub trait LocalEsdtAndEsdtNft { self.send() .esdt_system_sc_proxy() .issue_semi_fungible( - issue_cost.clone_value(), + issue_cost.clone(), &token_display_name, &token_ticker, SemiFungibleTokenProperties { diff --git a/contracts/feature-tests/composability/vault/src/vault.rs b/contracts/feature-tests/composability/vault/src/vault.rs index 47d7406ac4..38f9237ef8 100644 --- a/contracts/feature-tests/composability/vault/src/vault.rs +++ b/contracts/feature-tests/composability/vault/src/vault.rs @@ -51,10 +51,7 @@ pub trait Vault { } fn all_transfers_multi(&self) -> MultiValueEncoded { - self.call_value() - .all_transfers() - .clone_value() - .into_multi_value() + self.call_value().all_transfers().clone().into_multi_value() } #[payable("*")] diff --git a/contracts/feature-tests/payable-features/src/payable_features.rs b/contracts/feature-tests/payable-features/src/payable_features.rs index 5b0f18f39b..22c2cda5e7 100644 --- a/contracts/feature-tests/payable-features/src/payable_features.rs +++ b/contracts/feature-tests/payable-features/src/payable_features.rs @@ -25,7 +25,7 @@ pub trait PayableFeatures { #[view] #[payable("*")] fn echo_call_value(&self) -> ManagedVec { - self.call_value().all_transfers().clone_value() + self.call_value().all_transfers().clone() } #[endpoint] @@ -34,7 +34,7 @@ pub trait PayableFeatures { &self, #[payment_multi] payments: ManagedRef<'static, ManagedVec>>, ) -> ManagedVec> { - payments.clone_value() + payments.clone() } #[endpoint] @@ -104,7 +104,7 @@ pub trait PayableFeatures { &self, #[payment_token] token: EgldOrEsdtTokenIdentifier, ) -> MultiValue2 { - let payment = self.call_value().egld().clone_value(); + let payment = self.call_value().egld().clone(); (payment, token).into() } @@ -124,7 +124,7 @@ pub trait PayableFeatures { &self, #[payment_token] token: EgldOrEsdtTokenIdentifier, ) -> MultiValue2 { - let payment = self.call_value().egld().clone_value(); + let payment = self.call_value().egld().clone(); (payment, token).into() } @@ -133,7 +133,7 @@ pub trait PayableFeatures { fn payable_egld_4(&self) -> MultiValue2 { let payment = self.call_value().egld(); let token = self.call_value().egld_or_single_esdt().token_identifier; - (payment.clone_value(), token).into() + (payment.clone(), token).into() } #[endpoint] diff --git a/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs b/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs index 4c77692fb3..67157e0142 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs @@ -57,7 +57,7 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[payable("EGLD")] #[endpoint] fn receive_egld(&self) -> BigUint { - self.call_value().egld().clone_value() + self.call_value().egld().clone() } #[payable("EGLD")] @@ -95,7 +95,7 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[payable("*")] #[endpoint] fn receive_multi_esdt(&self) -> ManagedVec> { - self.call_value().all_esdt_transfers().clone_value() + self.call_value().all_esdt_transfers().clone() } #[payable("*")] diff --git a/contracts/modules/src/dns.rs b/contracts/modules/src/dns.rs index 782e0ad0b1..8b4706fcf9 100644 --- a/contracts/modules/src/dns.rs +++ b/contracts/modules/src/dns.rs @@ -13,7 +13,7 @@ pub trait DnsModule { #[only_owner] #[endpoint(dnsRegister)] fn dns_register(&self, dns_address: ManagedAddress, name: ManagedBuffer) { - let payment = self.call_value().egld().clone_value(); + let payment = self.call_value().egld().clone(); self.tx() .to(&dns_address) .typed(dns_proxy::DnsProxy) diff --git a/contracts/modules/src/esdt.rs b/contracts/modules/src/esdt.rs index a6aed9239e..4fd821b24b 100644 --- a/contracts/modules/src/esdt.rs +++ b/contracts/modules/src/esdt.rs @@ -34,7 +34,7 @@ pub trait EsdtModule { ) { require!(self.token_id().is_empty(), "Token already issued"); - let issue_cost = self.call_value().egld().clone_value(); + let issue_cost = self.call_value().egld().clone(); let num_decimals = match opt_num_decimals { OptionalValue::Some(d) => d, OptionalValue::None => 0, diff --git a/contracts/modules/src/token_merge/merged_token_setup.rs b/contracts/modules/src/token_merge/merged_token_setup.rs index 58bead8c9d..540293984c 100644 --- a/contracts/modules/src/token_merge/merged_token_setup.rs +++ b/contracts/modules/src/token_merge/merged_token_setup.rs @@ -17,7 +17,7 @@ pub trait MergedTokenSetupModule { let payment_amount = self.call_value().egld(); self.merged_token().issue_and_set_all_roles( EsdtTokenType::NonFungible, - payment_amount.clone_value(), + payment_amount.clone(), token_display_name, token_ticker, 0, diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index c6b2650781..10a0117af5 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -103,9 +103,7 @@ where /// Returns the EGLD call value from the VM as ManagedDecimal pub fn egld_decimal(&self) -> ManagedDecimal> { - ManagedDecimal::>::const_decimals_from_raw( - self.egld_value().clone_value(), - ) + ManagedDecimal::>::const_decimals_from_raw(self.egld_value().clone()) } /// Returns all ESDT transfers that accompany this SC call. @@ -239,7 +237,7 @@ where 0 => EgldOrEsdtTokenPayment { token_identifier: EgldOrEsdtTokenIdentifier::egld(), token_nonce: 0, - amount: self.egld_direct_non_strict().clone_value(), + amount: self.egld_direct_non_strict().clone(), }, 1 => esdt_transfers.get(0).clone(), _ => A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_ESDT_TRANSFERS.as_bytes()), @@ -269,9 +267,9 @@ where pub fn any_payment(&self) -> EgldOrMultiEsdtPayment { let esdt_transfers = self.all_esdt_transfers(); if esdt_transfers.is_empty() { - EgldOrMultiEsdtPayment::Egld(self.egld_direct_non_strict().clone_value()) + EgldOrMultiEsdtPayment::Egld(self.egld_direct_non_strict().clone()) } else { - EgldOrMultiEsdtPayment::MultiEsdt(esdt_transfers.clone_value()) + EgldOrMultiEsdtPayment::MultiEsdt(esdt_transfers.clone()) } } }