Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generate proxy with custom endpoints #1676

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions contracts/feature-tests/basic-features/sc-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ overflow-checks = true # needed for overflow tests
add-unlabelled = false
add-endpoints = ["init", "load_bytes", "store_bytes"]
kill_legacy_callback = true

[[proxy]]
path = "src/basic_features_proxy.rs"
custom-endpoints = [
"load_bytes"
]
10 changes: 10 additions & 0 deletions contracts/feature-tests/basic-features/src/basic_features_proxy.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
// 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 BasicFeaturesProxy;
Expand Down Expand Up @@ -53,6 +62,7 @@ where
To: TxTo<Env>,
Gas: TxGas<Env>,
{

pub fn load_bytes(
self,
) -> TxTypedCall<Env, From, To, NotPayable, Gas, ManagedBuffer<Env::Api>> {
Expand Down
1 change: 1 addition & 0 deletions contracts/feature-tests/basic-features/src/egld_decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ multiversx_sc::imports!();
/// Used for testing the egld_decimal function return type
#[multiversx_sc::module]
pub trait EgldDecimal {
#[custom_proxy]
#[payable("EGLD")]
#[endpoint]
fn returns_egld_decimal(&self) -> ManagedDecimal<Self::Api, ConstDecimals<18>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::types::*;
/// Storage tests: direct store.
#[multiversx_sc::module]
pub trait StorageStoreFeatures {
#[custom_proxy]
#[endpoint]
#[storage_set("storage_bytes")]
fn store_bytes(&self, bi: ManagedBuffer);
Expand Down
3 changes: 3 additions & 0 deletions framework/base/src/abi/endpoint_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub struct EndpointAbi {
pub inputs: Vec<InputAbi>,
pub outputs: OutputAbis,
pub allow_multiple_var_args: bool,
pub custom_proxy: bool,
}

impl EndpointAbi {
Expand All @@ -69,6 +70,7 @@ impl EndpointAbi {
payable_in_tokens: &[&str],
labels: &[&str],
allow_multiple_var_args: bool,
custom_proxy: bool,
) -> Self {
EndpointAbi {
docs: docs.iter().map(|s| s.to_string()).collect(),
Expand All @@ -83,6 +85,7 @@ impl EndpointAbi {
inputs: Vec::new(),
outputs: Vec::new(),
allow_multiple_var_args,
custom_proxy,
}
}

Expand Down
1 change: 1 addition & 0 deletions framework/base/src/external_view_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub fn external_view_contract_constructor_abi() -> EndpointAbi {
EndpointTypeAbi::Init,
&[],
&[],
false,
false
);
endpoint_abi.inputs.push(InputAbi {
Expand Down
8 changes: 7 additions & 1 deletion framework/derive/src/generate/abi_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::model::{
PublicRole,
};

#[allow(clippy::too_many_arguments)]
fn generate_endpoint_snippet(
m: &Method,
endpoint_name: &str,
Expand All @@ -12,6 +13,7 @@ fn generate_endpoint_snippet(
mutability: EndpointMutabilityMetadata,
endpoint_type: EndpointTypeMetadata,
allow_multiple_var_args: bool,
custom_proxy: bool,
) -> proc_macro2::TokenStream {
let endpoint_docs = &m.docs;
let rust_method_name = m.name.to_string();
Expand Down Expand Up @@ -52,7 +54,6 @@ fn generate_endpoint_snippet(
let label_names = &m.label_names;
let mutability_tokens = mutability.to_tokens();
let endpoint_type_tokens = endpoint_type.to_tokens();

quote! {
let mut endpoint_abi = multiversx_sc::abi::EndpointAbi::new(
&[ #(#endpoint_docs),* ],
Expand All @@ -65,6 +66,7 @@ fn generate_endpoint_snippet(
&[ #(#payable_in_tokens),* ],
&[ #(#label_names),* ],
#allow_multiple_var_args,
#custom_proxy
);
#(#input_snippets)*
#output_snippet
Expand All @@ -85,6 +87,7 @@ fn generate_endpoint_snippets(contract: &ContractTrait) -> Vec<proc_macro2::Toke
EndpointMutabilityMetadata::Mutable,
EndpointTypeMetadata::Init,
m.is_allow_multiple_var_args(),
m.is_custom_proxy(),
);
Some(quote! {
#endpoint_def
Expand All @@ -100,6 +103,7 @@ fn generate_endpoint_snippets(contract: &ContractTrait) -> Vec<proc_macro2::Toke
EndpointMutabilityMetadata::Mutable,
EndpointTypeMetadata::Upgrade,
m.is_allow_multiple_var_args(),
m.is_custom_proxy(),
);
Some(quote! {
#endpoint_def
Expand All @@ -115,6 +119,7 @@ fn generate_endpoint_snippets(contract: &ContractTrait) -> Vec<proc_macro2::Toke
endpoint_metadata.mutability.clone(),
EndpointTypeMetadata::Endpoint,
endpoint_metadata.allow_multiple_var_args,
endpoint_metadata.custom_proxy,
);
Some(quote! {
#endpoint_def
Expand All @@ -130,6 +135,7 @@ fn generate_endpoint_snippets(contract: &ContractTrait) -> Vec<proc_macro2::Toke
EndpointMutabilityMetadata::Mutable,
EndpointTypeMetadata::PromisesCallback,
m.is_allow_multiple_var_args(),
m.is_custom_proxy(),
);
Some(quote! {
#endpoint_def
Expand Down
1 change: 1 addition & 0 deletions framework/derive/src/model/argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,5 @@ pub struct TraitProperties {
pub only_user_account: bool,
pub allow_multiple_var_args: bool,
pub esdt_attribute: Vec<EsdtAttribute>,
pub custom_proxy: bool,
}
2 changes: 2 additions & 0 deletions framework/derive/src/model/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ pub struct EndpointMetadata {
pub only_user_account: bool,
pub mutability: EndpointMutabilityMetadata,
pub allow_multiple_var_args: bool,
pub custom_proxy: bool,
}

#[derive(Clone, Debug)]
pub struct CallbackMetadata {
pub callback_name: syn::Ident,
pub allow_multiple_var_args: bool,
pub custom_proxy: bool,
}

/// Method visibility from the point of view of the smart contract
Expand Down
12 changes: 12 additions & 0 deletions framework/derive/src/model/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ impl Method {
}
}

pub fn is_custom_proxy(&self) -> bool {
match &self.public_role {
PublicRole::Init(_init_metadata) => false,
PublicRole::Upgrade(_upgrade_metadata) => false,
PublicRole::Endpoint(endpoint_metadata) => endpoint_metadata.custom_proxy,
PublicRole::Callback(callback_metadata)
| PublicRole::CallbackPromise(callback_metadata) => callback_metadata.custom_proxy,
PublicRole::CallbackRaw => false,
PublicRole::Private => false,
}
}

pub fn is_allow_multiple_var_args(&self) -> bool {
match &self.public_role {
PublicRole::Init(init_metadata) => init_metadata.allow_multiple_var_args,
Expand Down
1 change: 1 addition & 0 deletions framework/derive/src/parse/attributes/attr_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ pub(super) static ATTR_PROXY: &str = "proxy";
pub(super) static ATTR_LABEL: &str = "label";
pub(super) static ATTR_ALLOW_MULTIPLE_VAR_ARGS: &str = "allow_multiple_var_args";
pub(super) static ATTR_UPGRADE: &str = "upgrade";
pub(super) static ATTR_CUSTOM_PROXY: &str = "custom_proxy";
4 changes: 4 additions & 0 deletions framework/derive/src/parse/attributes/endpoint_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ pub fn is_upgrade(attr: &syn::Attribute) -> bool {
is_attribute_with_no_args(attr, ATTR_UPGRADE)
}

pub fn is_custom_proxy(attr: &syn::Attribute) -> bool {
is_attribute_with_no_args(attr, ATTR_CUSTOM_PROXY)
}

#[derive(Clone, Debug)]
pub struct EndpointAttribute {
pub endpoint_name: Option<syn::Ident>,
Expand Down
21 changes: 19 additions & 2 deletions framework/derive/src/parse/endpoint_parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::model::{

use super::{
attributes::{
is_allow_multiple_var_args, is_callback_raw, is_init, is_only_admin, is_only_owner,
is_only_user_account, is_upgrade, CallbackAttribute, EndpointAttribute,
is_allow_multiple_var_args, is_callback_raw, is_custom_proxy, is_init, is_only_admin,
is_only_owner, is_only_user_account, is_upgrade, CallbackAttribute, EndpointAttribute,
ExternalViewAttribute, LabelAttribute, OutputNameAttribute, PromisesCallbackAttribute,
ViewAttribute,
},
Expand Down Expand Up @@ -66,6 +66,18 @@ pub fn process_allow_multiple_var_args_attribute(
is_allow_multiple_var_args
}

pub fn process_custom_proxy_attribute(
attr: &syn::Attribute,
pass_1_data: &mut MethodAttributesPass1,
) -> bool {
let is_custom_proxy = is_custom_proxy(attr);
if is_custom_proxy {
pass_1_data.custom_proxy = true;
}

is_custom_proxy
}

pub fn process_only_owner_attribute(
attr: &syn::Attribute,
pass_1_data: &mut MethodAttributesPass1,
Expand Down Expand Up @@ -119,6 +131,7 @@ pub fn process_endpoint_attribute(
only_user_account: pass_1_data.only_user_account,
mutability: EndpointMutabilityMetadata::Mutable,
allow_multiple_var_args: pass_1_data.allow_multiple_var_args,
custom_proxy: pass_1_data.custom_proxy,
});
})
.is_some()
Expand All @@ -144,6 +157,7 @@ pub fn process_view_attribute(
only_user_account: pass_1_data.only_user_account,
mutability: EndpointMutabilityMetadata::Readonly,
allow_multiple_var_args: pass_1_data.allow_multiple_var_args,
custom_proxy: pass_1_data.custom_proxy,
});
})
.is_some()
Expand All @@ -169,6 +183,7 @@ pub fn process_external_view_attribute(
only_user_account: pass_1_data.only_user_account,
mutability: EndpointMutabilityMetadata::Readonly,
allow_multiple_var_args: pass_1_data.allow_multiple_var_args,
custom_proxy: pass_1_data.custom_proxy,
});
})
.is_some()
Expand All @@ -195,6 +210,7 @@ pub fn process_callback_attribute(attr: &syn::Attribute, method: &mut Method) ->
method.public_role = PublicRole::Callback(CallbackMetadata {
callback_name: callback_ident,
allow_multiple_var_args: method.is_allow_multiple_var_args(),
custom_proxy: method.is_custom_proxy(),
});
})
.is_some()
Expand All @@ -211,6 +227,7 @@ pub fn process_promises_callback_attribute(attr: &syn::Attribute, method: &mut M
method.public_role = PublicRole::CallbackPromise(CallbackMetadata {
callback_name: callback_ident,
allow_multiple_var_args: method.is_allow_multiple_var_args(),
custom_proxy: method.is_custom_proxy(),
});
})
.is_some()
Expand Down
13 changes: 8 additions & 5 deletions framework/derive/src/parse/method_parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use super::{
process_storage_mapper_attribute, process_storage_set_attribute,
},
extract_method_args, process_allow_multiple_var_args_attribute, process_callback_attribute,
process_callback_raw_attribute, process_endpoint_attribute, process_external_view_attribute,
process_init_attribute, process_label_names_attribute, process_only_admin_attribute,
process_only_owner_attribute, process_only_user_account_attribute,
process_output_names_attribute, process_payable_attribute, process_promises_callback_attribute,
process_upgrade_attribute, process_view_attribute,
process_callback_raw_attribute, process_custom_proxy_attribute, process_endpoint_attribute,
process_external_view_attribute, process_init_attribute, process_label_names_attribute,
process_only_admin_attribute, process_only_owner_attribute,
process_only_user_account_attribute, process_output_names_attribute, process_payable_attribute,
process_promises_callback_attribute, process_upgrade_attribute, process_view_attribute,
};
pub struct MethodAttributesPass1 {
pub method_name: String,
Expand All @@ -21,6 +21,7 @@ pub struct MethodAttributesPass1 {
pub only_admin: bool,
pub only_user_account: bool,
pub allow_multiple_var_args: bool,
pub custom_proxy: bool,
}

pub fn process_method(m: &syn::TraitItemFn, trait_attributes: &TraitProperties) -> Method {
Expand All @@ -39,6 +40,7 @@ pub fn process_method(m: &syn::TraitItemFn, trait_attributes: &TraitProperties)
only_admin: trait_attributes.only_admin,
only_user_account: trait_attributes.only_user_account,
allow_multiple_var_args: trait_attributes.allow_multiple_var_args,
custom_proxy: trait_attributes.custom_proxy,
};
let mut first_pass_unprocessed_attributes = Vec::new();

Expand Down Expand Up @@ -94,6 +96,7 @@ fn process_attribute_first_pass(
|| process_only_admin_attribute(attr, first_pass_data)
|| process_only_user_account_attribute(attr, first_pass_data)
|| process_allow_multiple_var_args_attribute(attr, first_pass_data)
|| process_custom_proxy_attribute(attr, first_pass_data)
}

fn process_attributes_second_pass(
Expand Down
24 changes: 20 additions & 4 deletions framework/meta-lib/src/contract/generate_proxy/proxy_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,21 @@ where
self.write_upgrades();
}

let custom_endpoints = self.collect_custom_endpoints();

if !self.contract_abi.endpoints.is_empty() {
self.write_endpoints();
self.write_endpoints(&custom_endpoints);
}
}

fn collect_custom_endpoints(&mut self) -> Vec<String> {
let mut custom_endpoints = self.proxy_config.custom_proxy_endpoints.clone();
for endpoint_abi in self.contract_abi.endpoints.clone() {
if endpoint_abi.custom_proxy && !custom_endpoints.contains(&endpoint_abi.name) {
custom_endpoints.push(endpoint_abi.name)
}
}
custom_endpoints
}

fn write_types(&mut self) {
Expand Down Expand Up @@ -210,11 +222,15 @@ where
self.writeln("}");
}

fn write_endpoints(&mut self) {
fn write_endpoints(&mut self, custom_endpoints: &[String]) {
let endpoints: Vec<EndpointAbi> = self.contract_abi.endpoints.clone();

self.write_header_impl_endpoints();
for (i, endpoint_abi) in endpoints.into_iter().enumerate() {
if !custom_endpoints.is_empty() && !custom_endpoints.contains(&endpoint_abi.name) {
continue;
}

if i > 0 {
self.writeln("");
}
Expand Down Expand Up @@ -518,7 +534,7 @@ where

let processed_rust_type = process_rust_type(rust_type.to_string(), paths, processed_paths);

self.rename_path_with_custome_config(&processed_rust_type)
self.rename_path_with_custom_config(&processed_rust_type)
}

fn start_write_type(
Expand Down Expand Up @@ -573,7 +589,7 @@ where
self.writeln(" }");
}

fn rename_path_with_custome_config(&self, processed_type: &str) -> String {
fn rename_path_with_custom_config(&self, processed_type: &str) -> String {
let mut renamed_processed_type = processed_type.to_owned();

if let Some(paths_rename) = &self.proxy_config.path_rename {
Expand Down
5 changes: 5 additions & 0 deletions framework/meta-lib/src/contract/sc_config/sc_config_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ pub struct ProxyConfigSerde {

#[serde(default)]
pub variant: Option<String>,

#[serde(default)]
#[serde(rename = "custom-endpoints")]
pub custom_proxy_endpoints: Vec<String>,
}

impl ProxyConfigSerde {
Expand All @@ -27,6 +31,7 @@ impl ProxyConfigSerde {
override_import: None,
path_rename: None,
variant: None,
custom_proxy_endpoints: Vec::new(),
}
}
}
Expand Down
Loading
Loading