diff --git a/configs/peer/executor.wasm b/configs/peer/executor.wasm index f53330f1e72..9b1ba5ebdc5 100644 Binary files a/configs/peer/executor.wasm and b/configs/peer/executor.wasm differ diff --git a/smart_contract/executor/src/default.rs b/smart_contract/executor/src/default.rs index 50eed1b823e..6ac2bde0afb 100644 --- a/smart_contract/executor/src/default.rs +++ b/smart_contract/executor/src/default.rs @@ -1276,6 +1276,7 @@ pub mod parameter { pub mod role { use iroha_smart_contract::data_model::role::Role; + use role::tokens::AnyPermissionToken; use super::*; @@ -1292,29 +1293,27 @@ pub mod role { let role = Role::try_from(find_role_query_res).unwrap(); let mut unknown_tokens = Vec::new(); - for token in role.permissions() { - macro_rules! visit_internal { - ($token:ident) => { - if !is_genesis($executor) { - if let Err(error) = permission::ValidateGrantRevoke::$method( - &$token, - $authority, - $executor.block_height(), - ) - { - deny!($executor, error); - } + if !is_genesis($executor) { + for token in role.permissions() { + if let Ok(token) = AnyPermissionToken::try_from(token.clone()) { + if let Err(error) = permission::ValidateGrantRevoke::$method( + &token, + $authority, + $executor.block_height(), + ) { + deny!($executor, error); } - continue; - }; - } + } - tokens::map_token!(token => visit_internal); - unknown_tokens.push(token); + unknown_tokens.push(token); + } } - assert!(unknown_tokens.is_empty(), "Role contains unknown permission tokens: {unknown_tokens:?}"); + assert!( + unknown_tokens.is_empty(), + "Role contains unknown permission tokens: {unknown_tokens:?}" + ); execute!($executor, $isi) }; } @@ -1333,15 +1332,12 @@ pub mod role { for token in role.permissions() { iroha_smart_contract::debug!(&format!("Checking `{token:?}`")); - macro_rules! try_from_token { - ($token:ident) => { - let token = PermissionToken::from($token); - new_role = new_role.add_permission(token); - continue; - }; + if let Ok(any_token) = AnyPermissionToken::try_from(token.clone()) { + let token = PermissionToken::from(any_token); + new_role = new_role.add_permission(token); + continue; } - tokens::map_token!(token => try_from_token); unknown_tokens.push(token); } @@ -1578,6 +1574,8 @@ pub mod trigger { } pub mod permission_token { + use tokens::AnyPermissionToken; + use super::*; macro_rules! impl_validate { @@ -1586,26 +1584,22 @@ pub mod permission_token { let token = $isi.object().clone(); let account_id = $isi.destination_id().clone(); - macro_rules! visit_internal { - ($token:ident) => { - let token = PermissionToken::from($token.clone()); - let isi = <$isi_type>::permission(token, account_id); - if is_genesis($executor) { - execute!($executor, isi); - } - if let Err(error) = permission::ValidateGrantRevoke::$method( - &$token, - $authority, - $executor.block_height(), - ) { - deny!($executor, error); - } - + if let Ok(any_token) = AnyPermissionToken::try_from(token.clone()) { + let token = PermissionToken::from(any_token.clone()); + let isi = <$isi_type>::permission(token, account_id); + if is_genesis($executor) { execute!($executor, isi); - }; - } + } + if let Err(error) = permission::ValidateGrantRevoke::$method( + &any_token, + $authority, + $executor.block_height(), + ) { + deny!($executor, error); + } - tokens::map_token!(token => visit_internal); + execute!($executor, isi); + } deny!( $executor, diff --git a/smart_contract/executor/src/default/tokens.rs b/smart_contract/executor/src/default/tokens.rs index 7f7a7f67f88..6e90f0fa6aa 100644 --- a/smart_contract/executor/src/default/tokens.rs +++ b/smart_contract/executor/src/default/tokens.rs @@ -29,20 +29,6 @@ use crate::permission::{self, Token as _}; /// ``` macro_rules! declare_tokens { ($($($token_path:ident ::)+ { $token_ty:ident }),+ $(,)?) => { - macro_rules! map_token { - ($token:ident => $callback:ident) => { - match $token.definition_id().as_ref() { $( - stringify!($token_ty) => { - if let Ok(token) = <$($token_path::)+$token_ty>::try_from($token.clone()) { - $callback!(token); - } - } )+ - _ => {} - } - - }; - } - macro_rules! map_token_type { ($callback:ident) => { $( $callback!($($token_path::)+$token_ty); )+ @@ -51,16 +37,17 @@ macro_rules! declare_tokens { /// Enum with every default token #[allow(clippy::enum_variant_names)] + #[derive(Clone)] pub(crate) enum AnyPermissionToken { $( $token_ty($($token_path::)+$token_ty), )* } - impl TryFrom<::iroha_smart_contract::data_model::permission::PermissionToken> for AnyPermissionToken { + impl TryFrom<$crate::data_model::permission::PermissionToken> for AnyPermissionToken { type Error = $crate::permission::PermissionTokenConversionError; - fn try_from(token: ::iroha_smart_contract::data_model::permission::PermissionToken) -> Result { + fn try_from(token: $crate::data_model::permission::PermissionToken) -> Result { match token.definition_id().as_ref() { $( stringify!($token_ty) => { let token = <$($token_path::)+$token_ty>::try_from(token)?; @@ -71,7 +58,35 @@ macro_rules! declare_tokens { } } - pub(crate) use map_token; + impl From for $crate::data_model::permission::PermissionToken { + fn from(token: AnyPermissionToken) -> Self { + match token { + $( + AnyPermissionToken::$token_ty(token) => Self::from(token), + )* + } + } + } + + impl $crate::permission::ValidateGrantRevoke for AnyPermissionToken { + fn validate_grant(&self, authority: &AccountId, block_height: u64) -> Result { + match self { + $( + AnyPermissionToken::$token_ty(token) => token.validate_grant(authority, block_height), + )* + } + + } + + fn validate_revoke(&self, authority: &AccountId, block_height: u64) -> Result { + match self { + $( + AnyPermissionToken::$token_ty(token) => token.validate_revoke(authority, block_height), + )* + } + } + } + pub(crate) use map_token_type; }; }