From 65f9681f6773af6dc2c35df3b50abdb687bd70cc Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 11 Dec 2024 17:35:25 +0200 Subject: [PATCH 1/2] 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 2/2] 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) }