Skip to content

Commit

Permalink
Merge pull request #1898 from multiversx/method-call-refactor
Browse files Browse the repository at this point in the history
EndpointWrappers `call_*` method refactor
  • Loading branch information
andrei-marinica authored Dec 12, 2024
2 parents e74dada + de3b6df commit 8df600b
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -489,7 +486,7 @@ fn setup() -> (ScenarioWorld, Vec<Address>) {
.to(PRICE_AGGREGATOR_ADDRESS)
.egld(STAKE_AMOUNT)
.whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| {
sc.call_stake();
sc.stake();
});
}

Expand Down
8 changes: 4 additions & 4 deletions framework/derive/src/contract_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub fn contract_implementation(

impl<C> #trait_name_ident for C
where
C: AutoImpl #(#supertraits_main)*
C: AutoImpl #(#supertraits_main)*
{
#(#auto_impls)*

Expand All @@ -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<Self::Api>) -> multiversx_sc::types::CallbackSelectorResult<Self::Api> {
fn callback_selector(&mut self, mut ___cb_closure___: multiversx_sc::types::CallbackClosureForDeser<Self::Api>) -> multiversx_sc::types::CallbackSelectorResult<Self::Api> {
#callback_selector_body
}

fn callback(&self) {
fn callback(&mut self) {
#callback_body
}
}
Expand Down
4 changes: 2 additions & 2 deletions framework/derive/src/generate/endpoints_mod_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub fn generate_endpoints_mod(
A: multiversx_sc::api::VMApi ,
{
super::EndpointWrappers::callback(
&multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
&mut multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
);
}
}
Expand Down Expand Up @@ -93,7 +93,7 @@ fn generate_wasm_endpoint(
A: multiversx_sc::api::VMApi,
{
super::EndpointWrappers::#call_method_ident(
&multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
&mut multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
);
}
}
Expand Down
15 changes: 7 additions & 8 deletions framework/derive/src/generate/function_selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Self::Api as multiversx_sc::api::VMApi>::external_view_init_override() => {
multiversx_sc::external_view_contract::external_view_contract_constructor::<Self::Api>();
return true;
true
},
#(#match_arms)*
other => false
} {
return true;
other => {
#(#module_calls)*
false
}
}
#(#module_calls)*
false
}
}
2 changes: 1 addition & 1 deletion framework/derive/src/generate/method_call_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down
3 changes: 2 additions & 1 deletion framework/derive/src/generate/snippets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<A>::new();
EndpointWrappers::call(&mut obj, fn_name)
}
}
}
Expand Down
101 changes: 73 additions & 28 deletions framework/scenario/tests/contract_without_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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::<Self::Api>();
let result = self.version();
multiversx_sc::io::finish_multi::<Self::Api, _>(&result)
}

fn call_some_async(&self) {
fn call_some_async(&mut self) {
self.some_async();
multiversx_sc::io::finish_multi::<Self::Api, _>(&())
}

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;
Expand All @@ -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<Self::Api>,
) -> multiversx_sc::types::CallbackSelectorResult<Self::Api> {
multiversx_sc::types::CallbackSelectorResult::NotProcessed(___cb_closure___)
}
}

Expand Down Expand Up @@ -251,8 +254,6 @@ mod sample_adder {
/////////////////////////////////////////////////////////////////////////////////////////////////
pub trait AutoImpl: multiversx_sc::contract_base::ContractBase {}

// impl<C> super::module_1::AutoImpl for C where C: AutoImpl {}

impl<C> Adder for C
where
C: AutoImpl + super::module_1::AutoImpl,
Expand All @@ -277,15 +278,15 @@ mod sample_adder {
Adder + multiversx_sc::contract_base::ContractBase + super::module_1::EndpointWrappers
{
#[inline]
fn call_sum(&self) {
fn call_sum(&mut self) {
<Self::Api as multiversx_sc::api::VMApi>::init_static();
multiversx_sc::io::call_value_init::not_payable::<Self::Api>();
let () = multiversx_sc::io::load_endpoint_args::<Self::Api, ()>(());
let result = self.sum();
multiversx_sc::io::finish_multi::<Self::Api, _>(&result);
}
#[inline]
fn call_init(&self) {
fn call_init(&mut self) {
<Self::Api as multiversx_sc::api::VMApi>::init_static();
multiversx_sc::io::call_value_init::not_payable::<Self::Api>();
let (initial_value, ()) = multiversx_sc::io::load_endpoint_args::<
Expand All @@ -295,7 +296,7 @@ mod sample_adder {
self.init(initial_value);
}
#[inline]
fn call_upgrade(&self) {
fn call_upgrade(&mut self) {
<Self::Api as multiversx_sc::api::VMApi>::init_static();
multiversx_sc::io::call_value_init::not_payable::<Self::Api>();
let (initial_value, ()) = multiversx_sc::io::load_endpoint_args::<
Expand All @@ -305,7 +306,7 @@ mod sample_adder {
self.upgrade(initial_value);
}
#[inline]
fn call_add(&self) {
fn call_add(&mut self) {
<Self::Api as multiversx_sc::api::VMApi>::init_static();
multiversx_sc::io::call_value_init::not_payable::<Self::Api>();
let (value, ()) = multiversx_sc::io::load_endpoint_args::<
Expand All @@ -314,8 +315,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;
Expand Down Expand Up @@ -346,19 +347,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<Self::Api>,
) -> multiversx_sc::types::CallbackSelectorResult<Self::Api> {
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::<Self::Api>()
{
if let multiversx_sc::types::CallbackSelectorResult::NotProcessed(_) =
self::EndpointWrappers::callback_selector(self, ___cb_closure___)
{
multiversx_sc::api::ErrorApiImpl::signal_error(
&<Self::Api as multiversx_sc::api::ErrorApi>::error_api_impl(),
err_msg::CALLBACK_BAD_FUNC.as_bytes(),
);
}
}
}
}

impl<A> EndpointWrappers for multiversx_sc::contract_base::UniversalContractObj<A> where
Expand Down Expand Up @@ -441,39 +481,39 @@ mod sample_adder {
A: multiversx_sc::api::VMApi,
{
super::EndpointWrappers::call_sum(
&multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
&mut multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
);
}
pub fn init<A>()
where
A: multiversx_sc::api::VMApi,
{
super::EndpointWrappers::call_init(
&multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
&mut multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
);
}
pub fn upgrade<A>()
where
A: multiversx_sc::api::VMApi,
{
super::EndpointWrappers::call_upgrade(
&multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
&mut multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
);
}
pub fn add<A>()
where
A: multiversx_sc::api::VMApi,
{
super::EndpointWrappers::call_add(
&multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
&mut multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
);
}
pub fn callBack<A>()
where
A: multiversx_sc::api::VMApi,
{
super::EndpointWrappers::callback(
&multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
&mut multiversx_sc::contract_base::UniversalContractObj::<A>::new(),
);
}
}
Expand Down Expand Up @@ -597,7 +637,10 @@ mod sample_adder {
A: multiversx_sc::api::VMApi,
{
fn call(&self, fn_name: &str) -> bool {
EndpointWrappers::call(self, fn_name)
// creating a new object, which we can mutate
// because of dynamic traits, we cannot move `self`
let mut obj = multiversx_sc::contract_base::UniversalContractObj::<A>::new();
EndpointWrappers::call(&mut obj, fn_name)
}
}

Expand Down Expand Up @@ -770,8 +813,10 @@ fn contract_without_macros_basic() {

assert_eq!(BigInt::from(100), adder.version());

let adder = sample_adder::ContractBuilder.new_contract_obj::<SingleTxApi>();
assert!(!adder.call("invalid_endpoint"));

let adder = sample_adder::ContractBuilder.new_contract_obj::<SingleTxApi>();
assert!(adder.call("getSum"));

let mut own_proxy =
Expand Down

0 comments on commit 8df600b

Please sign in to comment.