Skip to content

Commit

Permalink
[fix] #3857: Unify permission tokens in executor
Browse files Browse the repository at this point in the history
Signed-off-by: Shanin Roman <[email protected]>
  • Loading branch information
Erigara committed Jan 9, 2024
1 parent b14ad7b commit 1b2b2cd
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 7 deletions.
Binary file modified configs/peer/executor.wasm
Binary file not shown.
7 changes: 7 additions & 0 deletions data_model/src/permission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ pub mod model {
use super::*;

/// Stored proof of the account having a permission for a certain action.
///
/// Since permission token is represented opaque to core
/// either executor or client should make sure that tokens are represented uniformly.
///
/// So that:
/// - payload A is equal to payload B then token A must be equal to token B
/// - and if payload A is't equal to B then token A mustn't be equal to token B
#[derive(
Debug,
Clone,
Expand Down
15 changes: 14 additions & 1 deletion smart_contract/executor/derive/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn impl_token(ident: &syn2::Ident, generics: &syn2::Generics) -> proc_macro2::To

fn impl_try_from_permission_token(ident: &syn2::Ident, generics: &syn2::Generics) -> TokenStream {
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let token_id = quote! { <Self as ::iroha_executor::permission::Token>::name() };
let token_id = quote! { <#ident #ty_generics as ::iroha_executor::permission::Token>::name() };

quote! {
impl #impl_generics ::core::convert::TryFrom<::iroha_executor::data_model::permission::PermissionToken> for #ident #ty_generics #where_clause {
Expand All @@ -63,5 +63,18 @@ fn impl_try_from_permission_token(ident: &syn2::Ident, generics: &syn2::Generics
.map_err(::iroha_executor::permission::PermissionTokenConversionError::Deserialize)
}
}

impl #impl_generics ::core::convert::From<#ident #ty_generics> for ::iroha_executor::data_model::permission::PermissionToken #where_clause {
fn from(token: #ident #ty_generics) -> Self {
let definition_id = #token_id;

let payload = ::iroha_executor::smart_contract::debug::DebugExpectExt::dbg_expect(
::serde_json::to_value::<#ident #ty_generics>(token),
"failed to serialize concrete permission token type. This is a bug."
);

::iroha_executor::data_model::permission::PermissionToken::new(definition_id, &payload)
}
}
}
}
33 changes: 27 additions & 6 deletions smart_contract/executor/src/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,8 @@ pub mod parameter {
}

pub mod role {
use iroha_smart_contract::data_model::role::Role;

use super::*;

macro_rules! impl_validate {
Expand Down Expand Up @@ -981,13 +983,16 @@ pub mod role {
) {
let role = isi.object().inner();

// Unify permission tokens inside role and deduplicate them
let mut new_role = Role::new(role.id().clone());
let mut unknown_tokens = Vec::new();
for token in role.permissions() {
iroha_smart_contract::debug!(&format!("Checking `{token:?}`"));

macro_rules! try_from_token {
($token:ident) => {
let _token = $token;
let token = PermissionToken::from($token);
new_role = new_role.add_permission(token);
continue;
};
}
Expand All @@ -1005,6 +1010,7 @@ pub mod role {
);
}

let isi = Register::role(new_role);
execute!(executor, isi);
}

Expand Down Expand Up @@ -1168,14 +1174,17 @@ pub mod permission_token {
use super::*;

macro_rules! impl_validate {
($executor:ident, $authority:ident, $isi:ident, $method:ident) => {
($executor:ident, $authority:ident, $isi:ident, $method:ident, $isi_type:ty) => {
// TODO: https://github.com/hyperledger/iroha/issues/4082
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(token, account_id);
if is_genesis($executor) {
execute!($executor, $isi);
execute!($executor, isi);
}
if let Err(error) = permission::ValidateGrantRevoke::$method(
&$token,
Expand All @@ -1185,7 +1194,7 @@ pub mod permission_token {
deny!($executor, error);
}

execute!($executor, $isi);
execute!($executor, isi);
};
}

Expand All @@ -1203,15 +1212,27 @@ pub mod permission_token {
authority: &AccountId,
isi: &Grant<PermissionToken>,
) {
impl_validate!(executor, authority, isi, validate_grant);
impl_validate!(
executor,
authority,
isi,
validate_grant,
Grant<PermissionToken>
);
}

pub fn visit_revoke_account_permission<V: Validate + ?Sized>(
executor: &mut V,
authority: &AccountId,
isi: &Revoke<PermissionToken>,
) {
impl_validate!(executor, authority, isi, validate_revoke);
impl_validate!(
executor,
authority,
isi,
validate_revoke,
Revoke<PermissionToken>
);
}
}

Expand Down

0 comments on commit 1b2b2cd

Please sign in to comment.