diff --git a/.github/workflows/iroha2-dev-pr-static.yml b/.github/workflows/iroha2-dev-pr-static.yml index 06effe3e687..bc44c92101e 100644 --- a/.github/workflows/iroha2-dev-pr-static.yml +++ b/.github/workflows/iroha2-dev-pr-static.yml @@ -47,10 +47,10 @@ jobs: run: cargo fmt --all -- --check - name: Lints without features if: always() - run: cargo clippy -Zlints --workspace --benches --tests --examples --no-default-features --quiet + run: cargo clippy --workspace --benches --tests --examples --no-default-features --quiet - name: Lints with all features enabled if: always() - run: cargo clippy -Zlints --workspace --benches --tests --examples --all-features --quiet + run: cargo clippy --workspace --benches --tests --examples --all-features --quiet - name: Documentation if: always() run: cargo doc --no-deps --quiet diff --git a/client/tests/integration/asset.rs b/client/tests/integration/asset.rs index beac868a71a..9ac0687fbaa 100644 --- a/client/tests/integration/asset.rs +++ b/client/tests/integration/asset.rs @@ -269,7 +269,7 @@ fn find_rate_and_make_exchange_isi_should_succeed() { }; let grant_alice_asset_transfer_permission = |asset_id: AssetId, owner_keypair: KeyPair| { - let allow_alice_to_transfer_asset = Grant::permission_token( + let allow_alice_to_transfer_asset = Grant::permission( PermissionToken::new( "CanTransferUserAsset".parse().unwrap(), &json!({ "asset_id": asset_id }), diff --git a/client/tests/integration/domain_owner.rs b/client/tests/integration/domain_owner.rs index b159fa34cbd..2ffc467ac42 100644 --- a/client/tests/integration/domain_owner.rs +++ b/client/tests/integration/domain_owner.rs @@ -8,15 +8,59 @@ use test_network::*; #[test] fn domain_owner_domain_permissions() -> Result<()> { + let chain_id = ChainId::new("0"); + let (_rt, _peer, test_client) = ::new().with_port(11_080).start_with_runtime(); wait_for_genesis_committed(&[test_client.clone()], 0); let kingdom_id: DomainId = "kingdom".parse()?; + let bob_id: AccountId = "bob@kingdom".parse()?; + let coin_id: AssetDefinitionId = "coin#kingdom".parse()?; + let coin = AssetDefinition::quantity(coin_id.clone()); // "alice@wonderland" is owner of "kingdom" domain let kingdom = Domain::new(kingdom_id.clone()); test_client.submit_blocking(Register::domain(kingdom))?; + let bob_keypair = KeyPair::generate()?; + let bob = Account::new(bob_id.clone(), [bob_keypair.public_key().clone()]); + test_client.submit_blocking(Register::account(bob))?; + + // Asset definitions can't be registered by "bob@kingdom" by default + let transaction = TransactionBuilder::new(chain_id.clone(), bob_id.clone()) + .with_instructions([Register::asset_definition(coin.clone())]) + .sign(bob_keypair.clone())?; + let err = test_client + .submit_transaction_blocking(&transaction) + .expect_err("Tx should fail due to permissions"); + + let rejection_reason = err + .downcast_ref::() + .unwrap_or_else(|| panic!("Error {err} is not PipelineRejectionReason")); + + assert!(matches!( + rejection_reason, + &PipelineRejectionReason::Transaction(TransactionRejectionReason::Validation( + ValidationFail::NotPermitted(_) + )) + )); + + // "alice@wonderland" owns the domain and can register AssetDefinitions by default as domain owner + test_client.submit_blocking(Register::asset_definition(coin.clone()))?; + test_client.submit_blocking(Unregister::asset_definition(coin_id))?; + + // Granting a respective token also allows "bob@kingdom" to do so + let token = PermissionToken::new( + "CanRegisterAssetDefinitionInDomain".parse().unwrap(), + &json!({ "domain_id": kingdom_id }), + ); + test_client.submit_blocking(Grant::permission(token.clone(), bob_id.clone()))?; + let transaction = TransactionBuilder::new(chain_id, bob_id.clone()) + .with_instructions([Register::asset_definition(coin)]) + .sign(bob_keypair)?; + test_client.submit_transaction_blocking(&transaction)?; + test_client.submit_blocking(Revoke::permission(token, bob_id.clone()))?; + // check that "alice@wonderland" as owner of domain can edit metadata in her domain let key: Name = "key".parse()?; let value: Name = "value".parse()?; @@ -24,13 +68,12 @@ fn domain_owner_domain_permissions() -> Result<()> { test_client.submit_blocking(RemoveKeyValue::domain(kingdom_id.clone(), key))?; // check that "alice@wonderland" as owner of domain can grant and revoke domain related permission tokens - let bob_id: AccountId = "bob@wonderland".parse()?; let token = PermissionToken::new( "CanUnregisterDomain".parse().unwrap(), &json!({ "domain_id": kingdom_id }), ); - test_client.submit_blocking(Grant::permission_token(token.clone(), bob_id.clone()))?; - test_client.submit_blocking(Revoke::permission_token(token, bob_id))?; + test_client.submit_blocking(Grant::permission(token.clone(), bob_id.clone()))?; + test_client.submit_blocking(Revoke::permission(token, bob_id))?; // check that "alice@wonderland" as owner of domain can unregister her domain test_client.submit_blocking(Unregister::domain(kingdom_id))?; @@ -90,8 +133,8 @@ fn domain_owner_account_permissions() -> Result<()> { "CanUnregisterAccount".parse().unwrap(), &json!({ "account_id": mad_hatter_id }), ); - test_client.submit_blocking(Grant::permission_token(token.clone(), bob_id.clone()))?; - test_client.submit_blocking(Revoke::permission_token(token, bob_id))?; + test_client.submit_blocking(Grant::permission(token.clone(), bob_id.clone()))?; + test_client.submit_blocking(Revoke::permission(token, bob_id))?; // check that "alice@wonderland" as owner of domain can unregister accounts in her domain test_client.submit_blocking(Unregister::account(mad_hatter_id))?; @@ -111,7 +154,7 @@ fn domain_owner_asset_definition_permissions() -> Result<()> { let coin_id: AssetDefinitionId = "coin#kingdom".parse()?; // "alice@wonderland" is owner of "kingdom" domain - let kingdom = Domain::new(kingdom_id); + let kingdom = Domain::new(kingdom_id.clone()); test_client.submit_blocking(Register::domain(kingdom))?; let bob_keypair = KeyPair::generate()?; @@ -121,6 +164,13 @@ fn domain_owner_asset_definition_permissions() -> Result<()> { let rabbit = Account::new(rabbit_id.clone(), []); test_client.submit_blocking(Register::account(rabbit))?; + // Grant permission to register asset definitions to "bob@kingdom" + let token = PermissionToken::new( + "CanRegisterAssetDefinitionInDomain".parse().unwrap(), + &json!({ "domain_id": kingdom_id }), + ); + test_client.submit_blocking(Grant::permission(token, bob_id.clone()))?; + // register asset definitions by "bob@kingdom" so he is owner of it let coin = AssetDefinition::quantity(coin_id.clone()); let transaction = TransactionBuilder::new(chain_id, bob_id.clone()) @@ -151,8 +201,8 @@ fn domain_owner_asset_definition_permissions() -> Result<()> { "CanUnregisterAssetDefinition".parse().unwrap(), &json!({ "asset_definition_id": coin_id }), ); - test_client.submit_blocking(Grant::permission_token(token.clone(), bob_id.clone()))?; - test_client.submit_blocking(Revoke::permission_token(token, bob_id))?; + test_client.submit_blocking(Grant::permission(token.clone(), bob_id.clone()))?; + test_client.submit_blocking(Revoke::permission(token, bob_id))?; // check that "alice@wonderland" as owner of domain can unregister asset definitions in her domain test_client.submit_blocking(Unregister::asset_definition(coin_id))?; @@ -174,13 +224,20 @@ fn domain_owner_asset_permissions() -> Result<()> { let store_id: AssetDefinitionId = "store#kingdom".parse()?; // "alice@wonderland" is owner of "kingdom" domain - let kingdom = Domain::new(kingdom_id); + let kingdom = Domain::new(kingdom_id.clone()); test_client.submit_blocking(Register::domain(kingdom))?; let bob_keypair = KeyPair::generate()?; let bob = Account::new(bob_id.clone(), [bob_keypair.public_key().clone()]); test_client.submit_blocking(Register::account(bob))?; + // Grant permission to register asset definitions to "bob@kingdom" + let token = PermissionToken::new( + "CanRegisterAssetDefinitionInDomain".parse().unwrap(), + &json!({ "domain_id": kingdom_id }), + ); + test_client.submit_blocking(Grant::permission(token, bob_id.clone()))?; + // register asset definitions by "bob@kingdom" so he is owner of it let coin = AssetDefinition::quantity(coin_id.clone()); let store = AssetDefinition::store(store_id.clone()); @@ -216,8 +273,8 @@ fn domain_owner_asset_permissions() -> Result<()> { "CanUnregisterUserAsset".parse().unwrap(), &json!({ "asset_id": bob_store_id }), ); - test_client.submit_blocking(Grant::permission_token(token.clone(), bob_id.clone()))?; - test_client.submit_blocking(Revoke::permission_token(token, bob_id))?; + test_client.submit_blocking(Grant::permission(token.clone(), bob_id.clone()))?; + test_client.submit_blocking(Revoke::permission(token, bob_id))?; Ok(()) } @@ -273,8 +330,8 @@ fn domain_owner_trigger_permissions() -> Result<()> { "CanUnregisterUserTrigger".parse().unwrap(), &json!({ "trigger_id": trigger_id }), ); - test_client.submit_blocking(Grant::permission_token(token.clone(), bob_id.clone()))?; - test_client.submit_blocking(Revoke::permission_token(token, bob_id))?; + test_client.submit_blocking(Grant::permission(token.clone(), bob_id.clone()))?; + test_client.submit_blocking(Revoke::permission(token, bob_id))?; // check that "alice@wonderland" as owner of domain can unregister triggers in her domain test_client.submit_blocking(Unregister::trigger(trigger_id))?; diff --git a/client/tests/integration/permissions.rs b/client/tests/integration/permissions.rs index beb8ffd6de0..6aa19bb0709 100644 --- a/client/tests/integration/permissions.rs +++ b/client/tests/integration/permissions.rs @@ -17,7 +17,7 @@ fn genesis_transactions_are_validated() { // Setting up genesis - let genesis = GenesisNetwork::test_with_instructions([Grant::permission_token( + let genesis = GenesisNetwork::test_with_instructions([Grant::permission( PermissionToken::new("InvalidToken".parse().unwrap(), &json!(null)), AccountId::from_str("alice@wonderland").unwrap(), ) @@ -224,7 +224,7 @@ fn permissions_differ_not_only_by_names() { // Granting permission to Alice to modify metadata in Mouse's hats let mouse_hat_id = AssetId::new(hat_definition_id, mouse_id.clone()); - let allow_alice_to_set_key_value_in_hats = Grant::permission_token( + let allow_alice_to_set_key_value_in_hats = Grant::permission( PermissionToken::new( "CanSetKeyValueInUserAsset".parse().unwrap(), &json!({ "asset_id": mouse_hat_id }), @@ -261,7 +261,7 @@ fn permissions_differ_not_only_by_names() { .expect_err("Expected Alice to fail to modify Mouse's shoes"); // Granting permission to Alice to modify metadata in Mouse's shoes - let allow_alice_to_set_key_value_in_shoes = Grant::permission_token( + let allow_alice_to_set_key_value_in_shoes = Grant::permission( PermissionToken::new( "CanSetKeyValueInUserAsset".parse().unwrap(), &json!({ "asset_id": mouse_shoes_id }), @@ -312,7 +312,7 @@ fn stored_vs_granted_token_payload() -> Result<()> { // Allow alice to mint mouse asset and mint initial value let mouse_asset = AssetId::new(asset_definition_id, mouse_id.clone()); - let allow_alice_to_set_key_value_in_mouse_asset = Grant::permission_token( + let allow_alice_to_set_key_value_in_mouse_asset = Grant::permission( PermissionToken::from_str_unchecked( "CanSetKeyValueInUserAsset".parse().unwrap(), // NOTE: Introduced additional whitespaces in the serialized form @@ -347,7 +347,7 @@ fn permission_tokens_are_unified() { // Given let alice_id = AccountId::from_str("alice@wonderland").expect("Valid"); - let allow_alice_to_transfer_rose_1 = Grant::permission_token( + let allow_alice_to_transfer_rose_1 = Grant::permission( PermissionToken::from_str_unchecked( "CanTransferUserAsset".parse().unwrap(), // NOTE: Introduced additional whitespaces in the serialized form @@ -356,7 +356,7 @@ fn permission_tokens_are_unified() { alice_id.clone(), ); - let allow_alice_to_transfer_rose_2 = Grant::permission_token( + let allow_alice_to_transfer_rose_2 = Grant::permission( PermissionToken::from_str_unchecked( "CanTransferUserAsset".parse().unwrap(), // NOTE: Introduced additional whitespaces in the serialized form diff --git a/client/tests/integration/smartcontracts/create_nft_for_every_user_trigger/src/lib.rs b/client/tests/integration/smartcontracts/create_nft_for_every_user_trigger/src/lib.rs index bce2802adcb..d9df633498d 100644 --- a/client/tests/integration/smartcontracts/create_nft_for_every_user_trigger/src/lib.rs +++ b/client/tests/integration/smartcontracts/create_nft_for_every_user_trigger/src/lib.rs @@ -21,9 +21,18 @@ fn main(_owner: AccountId, _event: Event) { let limits = MetadataLimits::new(256, 256); + let bad_domain_ids: [DomainId; 2] = [ + "genesis".parse().dbg_unwrap(), + "garden_of_live_flowers".parse().dbg_unwrap(), + ]; + for account in accounts_cursor { let account = account.dbg_unwrap(); + if bad_domain_ids.contains(account.id().domain_id()) { + continue; + } + let mut metadata = Metadata::new(); let name = format!( "nft_for_{}_in_{}", diff --git a/client/tests/integration/smartcontracts/executor_with_custom_token/src/lib.rs b/client/tests/integration/smartcontracts/executor_with_custom_token/src/lib.rs index bd9322a7f87..65c48e2db59 100644 --- a/client/tests/integration/smartcontracts/executor_with_custom_token/src/lib.rs +++ b/client/tests/integration/smartcontracts/executor_with_custom_token/src/lib.rs @@ -118,7 +118,7 @@ impl Executor { accounts .iter() .try_for_each(|(account, domain_id)| { - Revoke::permission_token( + Revoke::permission( PermissionToken::new( can_unregister_domain_definition_id.clone(), &json!({ "domain_id": domain_id }), @@ -137,7 +137,7 @@ impl Executor { ) })?; - Grant::permission_token( + Grant::permission( PermissionToken::new( can_control_domain_lives_definition_id.clone(), &json!(null), diff --git a/client_cli/src/main.rs b/client_cli/src/main.rs index 05b9121302c..2084d35d562 100644 --- a/client_cli/src/main.rs +++ b/client_cli/src/main.rs @@ -724,7 +724,7 @@ mod account { permission, metadata, } = self; - let grant = iroha_client::data_model::isi::Grant::permission_token(permission.0, id); + let grant = iroha_client::data_model::isi::Grant::permission(permission.0, id); submit([grant], metadata.load()?, context) .wrap_err("Failed to grant the permission to the account") } diff --git a/configs/peer/executor.wasm b/configs/peer/executor.wasm index 194481b0e0d..24b10645278 100644 Binary files a/configs/peer/executor.wasm and b/configs/peer/executor.wasm differ diff --git a/core/benches/blocks/common.rs b/core/benches/blocks/common.rs index f8969b2f16b..1b492d1fb89 100644 --- a/core/benches/blocks/common.rs +++ b/core/benches/blocks/common.rs @@ -66,7 +66,7 @@ pub fn populate_wsv( let domain_id = construct_domain_id(i); let domain = Domain::new(domain_id.clone()); instructions.push(Register::domain(domain).into()); - let can_unregister_domain = Grant::permission_token( + let can_unregister_domain = Grant::permission( PermissionToken::new( "CanUnregisterDomain".parse().unwrap(), &json!({ "domain_id": domain_id.clone() }), @@ -78,7 +78,7 @@ pub fn populate_wsv( let account_id = construct_account_id(j, domain_id.clone()); let account = Account::new(account_id.clone(), []); instructions.push(Register::account(account).into()); - let can_unregister_account = Grant::permission_token( + let can_unregister_account = Grant::permission( PermissionToken::new( "CanUnregisterAccount".parse().unwrap(), &json!({ "account_id": account_id.clone() }), @@ -94,7 +94,7 @@ pub fn populate_wsv( iroha_data_model::asset::AssetValueType::Quantity, ); instructions.push(Register::asset_definition(asset_definition).into()); - let can_unregister_asset_definition = Grant::permission_token( + let can_unregister_asset_definition = Grant::permission( PermissionToken::new( "CanUnregisterAssetDefinition".parse().unwrap(), &json!({ "asset_definition_id": asset_definition_id }), diff --git a/core/test_network/src/lib.rs b/core/test_network/src/lib.rs index 90686cde43f..24935e2a49a 100644 --- a/core/test_network/src/lib.rs +++ b/core/test_network/src/lib.rs @@ -94,11 +94,11 @@ impl TestGenesis for GenesisNetwork { let alice_id = AccountId::from_str("alice@wonderland").expect("valid names"); let mint_rose_permission = PermissionToken::new( - "CanMintAssetsWithDefinition".parse().unwrap(), + "CanMintAssetWithDefinition".parse().unwrap(), &json!({ "asset_definition_id": rose_definition_id }), ); let burn_rose_permission = PermissionToken::new( - "CanBurnAssetsWithDefinition".parse().unwrap(), + "CanBurnAssetWithDefinition".parse().unwrap(), &json!({ "asset_definition_id": rose_definition_id }), ); let unregister_any_peer_permission = @@ -111,6 +111,14 @@ impl TestGenesis for GenesisNetwork { ); let upgrade_executor_permission = PermissionToken::new("CanUpgradeExecutor".parse().unwrap(), &json!(null)); + let register_account_permission = PermissionToken::new( + "CanRegisterAccountInDomain".parse().unwrap(), + &json!({ "domain_id": DomainId::from_str("wonderland").unwrap() } ), + ); + let register_asset_definitions_permission = PermissionToken::new( + "CanRegisterAssetDefinitionInDomain".parse().unwrap(), + &json!({ "domain_id": DomainId::from_str("wonderland").unwrap() } ), + ); let first_transaction = genesis .first_transaction_mut() @@ -122,9 +130,11 @@ impl TestGenesis for GenesisNetwork { unregister_any_role_permission, unregister_wonderland_domain, upgrade_executor_permission, + register_account_permission, + register_asset_definitions_permission, ] { first_transaction - .append_instruction(Grant::permission_token(permission, alice_id.clone()).into()); + .append_instruction(Grant::permission(permission, alice_id.clone()).into()); } for isi in extra_isi.into_iter() { diff --git a/data_model/src/isi.rs b/data_model/src/isi.rs index 4bbfa0de0d7..94f039982e7 100644 --- a/data_model/src/isi.rs +++ b/data_model/src/isi.rs @@ -902,7 +902,7 @@ mod transparent { impl Grant { /// Constructs a new [`Grant`] for a [`PermissionToken`]. - pub fn permission_token(permission_token: PermissionToken, to: AccountId) -> Self { + pub fn permission(permission_token: PermissionToken, to: AccountId) -> Self { Self { object: permission_token, destination_id: to, @@ -947,7 +947,7 @@ mod transparent { impl Revoke { /// Constructs a new [`Revoke`] for a [`PermissionToken`]. - pub fn permission_token(permission_token: PermissionToken, from: AccountId) -> Self { + pub fn permission(permission_token: PermissionToken, from: AccountId) -> Self { Self { object: permission_token, destination_id: from, diff --git a/smart_contract/executor/derive/src/lib.rs b/smart_contract/executor/derive/src/lib.rs index 71d682c974c..c9bc81dc6d8 100644 --- a/smart_contract/executor/derive/src/lib.rs +++ b/smart_contract/executor/derive/src/lib.rs @@ -128,6 +128,7 @@ pub fn derive_token(input: TokenStream) -> Result { /// - `asset_definition::Owner` - checks if the authority is the asset definition owner; /// - `asset::Owner` - checks if the authority is the asset owner; /// - `account::Owner` - checks if the authority is the account owner. +/// - `domain::Owner` - checks if the authority is the domain owner. /// - `AlwaysPass` - checks nothing and always passes. /// - `OnlyGenesis` - checks that block height is 0. /// diff --git a/smart_contract/executor/src/default.rs b/smart_contract/executor/src/default.rs index 0c7eafa30f2..81a6ba438b4 100644 --- a/smart_contract/executor/src/default.rs +++ b/smart_contract/executor/src/default.rs @@ -57,6 +57,11 @@ pub fn default_permission_token_schema() -> PermissionTokenSchema { schema } +// NOTE: If any new `visit_..` functions are introduced in this module, one should +// not forget to update the default executor boilerplate too, specifically the +// `iroha_executor::derive::default::impl_derive_visit` function +// signature list. + /// Default validation for [`SignedTransaction`]. /// /// # Warning @@ -282,10 +287,28 @@ pub mod account { pub fn visit_register_account( executor: &mut V, - _authority: &AccountId, + authority: &AccountId, isi: &Register, ) { - execute!(executor, isi) + let domain_id = isi.object().id().domain_id(); + + match permission::domain::is_domain_owner(domain_id, authority) { + Err(err) => deny!(executor, err), + Ok(true) => execute!(executor, isi), + Ok(false) => {} + } + + let can_register_account_in_domain = tokens::domain::CanRegisterAccountInDomain { + domain_id: domain_id.clone(), + }; + if can_register_account_in_domain.is_owned_by(authority) { + execute!(executor, isi); + } + + deny!( + executor, + "Can't register account in a domain owned by another account" + ); } pub fn visit_unregister_account( @@ -458,10 +481,29 @@ pub mod asset_definition { pub fn visit_register_asset_definition( executor: &mut V, - _authority: &AccountId, + authority: &AccountId, isi: &Register, ) { - execute!(executor, isi); + let domain_id = isi.object().id().domain_id(); + + match permission::domain::is_domain_owner(domain_id, authority) { + Err(err) => deny!(executor, err), + Ok(true) => execute!(executor, isi), + Ok(false) => {} + } + + let can_register_asset_definition_in_domain_token = + tokens::domain::CanRegisterAssetDefinitionInDomain { + domain_id: domain_id.clone(), + }; + if can_register_asset_definition_in_domain_token.is_owned_by(authority) { + execute!(executor, isi); + } + + deny!( + executor, + "Can't register asset definition in a domain owned by another account" + ); } pub fn visit_unregister_asset_definition( @@ -489,7 +531,7 @@ pub mod asset_definition { deny!( executor, - "Can't unregister assets registered by other accounts" + "Can't unregister asset definition in a domain owned by another account" ); } @@ -603,7 +645,7 @@ pub mod asset { Ok(false) => {} } let can_register_assets_with_definition_token = - tokens::asset::CanRegisterAssetsWithDefinition { + tokens::asset::CanRegisterAssetWithDefinition { asset_definition_id: asset.id().definition_id().clone(), }; if can_register_assets_with_definition_token.is_owned_by(authority) { @@ -637,7 +679,7 @@ pub mod asset { Ok(false) => {} } let can_unregister_assets_with_definition_token = - tokens::asset::CanUnregisterAssetsWithDefinition { + tokens::asset::CanUnregisterAssetWithDefinition { asset_definition_id: asset_id.definition_id().clone(), }; if can_unregister_assets_with_definition_token.is_owned_by(authority) { @@ -668,12 +710,18 @@ pub mod asset { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_mint_assets_with_definition_token = tokens::asset::CanMintAssetsWithDefinition { + let can_mint_assets_with_definition_token = tokens::asset::CanMintAssetWithDefinition { asset_definition_id: asset_id.definition_id().clone(), }; if can_mint_assets_with_definition_token.is_owned_by(authority) { execute!(executor, isi); } + let can_mint_user_asset_token = tokens::asset::CanMintUserAsset { + asset_id: asset_id.clone(), + }; + if can_mint_user_asset_token.is_owned_by(authority) { + execute!(executor, isi); + } deny!( executor, @@ -725,7 +773,7 @@ pub mod asset { Ok(true) => execute!(executor, isi), Ok(false) => {} } - let can_burn_assets_with_definition_token = tokens::asset::CanBurnAssetsWithDefinition { + let can_burn_assets_with_definition_token = tokens::asset::CanBurnAssetWithDefinition { asset_definition_id: asset_id.definition_id().clone(), }; if can_burn_assets_with_definition_token.is_owned_by(authority) { @@ -789,7 +837,7 @@ pub mod asset { Ok(false) => {} } let can_transfer_assets_with_definition_token = - tokens::asset::CanTransferAssetsWithDefinition { + tokens::asset::CanTransferAssetWithDefinition { asset_definition_id: asset_id.definition_id().clone(), }; if can_transfer_assets_with_definition_token.is_owned_by(authority) { @@ -1182,7 +1230,7 @@ pub mod permission_token { macro_rules! visit_internal { ($token:ident) => { let token = PermissionToken::from($token.clone()); - let isi = <$isi_type>::permission_token(token, account_id); + let isi = <$isi_type>::permission(token, account_id); if is_genesis($executor) { execute!($executor, isi); } diff --git a/smart_contract/executor/src/default/tokens.rs b/smart_contract/executor/src/default/tokens.rs index 97382cc7806..3deb532f5eb 100644 --- a/smart_contract/executor/src/default/tokens.rs +++ b/smart_contract/executor/src/default/tokens.rs @@ -70,6 +70,8 @@ declare_tokens! { crate::default::tokens::domain::{CanUnregisterDomain}, crate::default::tokens::domain::{CanSetKeyValueInDomain}, crate::default::tokens::domain::{CanRemoveKeyValueInDomain}, + crate::default::tokens::domain::{CanRegisterAccountInDomain}, + crate::default::tokens::domain::{CanRegisterAssetDefinitionInDomain}, crate::default::tokens::account::{CanUnregisterAccount}, crate::default::tokens::account::{CanMintUserPublicKeys}, @@ -82,13 +84,14 @@ declare_tokens! { crate::default::tokens::asset_definition::{CanSetKeyValueInAssetDefinition}, crate::default::tokens::asset_definition::{CanRemoveKeyValueInAssetDefinition}, - crate::default::tokens::asset::{CanRegisterAssetsWithDefinition}, - crate::default::tokens::asset::{CanUnregisterAssetsWithDefinition}, + crate::default::tokens::asset::{CanRegisterAssetWithDefinition}, + crate::default::tokens::asset::{CanUnregisterAssetWithDefinition}, crate::default::tokens::asset::{CanUnregisterUserAsset}, - crate::default::tokens::asset::{CanBurnAssetsWithDefinition}, + crate::default::tokens::asset::{CanBurnAssetWithDefinition}, + crate::default::tokens::asset::{CanMintAssetWithDefinition}, + crate::default::tokens::asset::{CanMintUserAsset}, crate::default::tokens::asset::{CanBurnUserAsset}, - crate::default::tokens::asset::{CanMintAssetsWithDefinition}, - crate::default::tokens::asset::{CanTransferAssetsWithDefinition}, + crate::default::tokens::asset::{CanTransferAssetWithDefinition}, crate::default::tokens::asset::{CanTransferUserAsset}, crate::default::tokens::asset::{CanSetKeyValueInUserAsset}, crate::default::tokens::asset::{CanRemoveKeyValueInUserAsset}, @@ -146,6 +149,22 @@ pub mod domain { pub domain_id: DomainId, } } + + token! { + #[derive(ValidateGrantRevoke, permission::derive_conversions::domain::Owner)] + #[validate(permission::domain::Owner)] + pub struct CanRegisterAccountInDomain { + pub domain_id: DomainId, + } + } + + token! { + #[derive(ValidateGrantRevoke, permission::derive_conversions::domain::Owner)] + #[validate(permission::domain::Owner)] + pub struct CanRegisterAssetDefinitionInDomain { + pub domain_id: DomainId, + } + } } pub mod account { @@ -229,7 +248,7 @@ pub mod asset { token! { #[derive(ValidateGrantRevoke, permission::derive_conversions::asset_definition::Owner)] #[validate(permission::asset_definition::Owner)] - pub struct CanRegisterAssetsWithDefinition { + pub struct CanRegisterAssetWithDefinition { pub asset_definition_id: AssetDefinitionId, } } @@ -237,7 +256,7 @@ pub mod asset { token! { #[derive(ValidateGrantRevoke, permission::derive_conversions::asset_definition::Owner)] #[validate(permission::asset_definition::Owner)] - pub struct CanUnregisterAssetsWithDefinition { + pub struct CanUnregisterAssetWithDefinition { pub asset_definition_id: AssetDefinitionId, } } @@ -253,7 +272,7 @@ pub mod asset { token! { #[derive(ValidateGrantRevoke, permission::derive_conversions::asset_definition::Owner)] #[validate(permission::asset_definition::Owner)] - pub struct CanBurnAssetsWithDefinition { + pub struct CanBurnAssetWithDefinition { pub asset_definition_id: AssetDefinitionId, } } @@ -269,15 +288,23 @@ pub mod asset { token! { #[derive(ValidateGrantRevoke, permission::derive_conversions::asset_definition::Owner)] #[validate(permission::asset_definition::Owner)] - pub struct CanMintAssetsWithDefinition { + pub struct CanMintAssetWithDefinition { pub asset_definition_id: AssetDefinitionId, } } + token! { + #[derive(ValidateGrantRevoke, permission::derive_conversions::asset::Owner)] + #[validate(permission::asset::Owner)] + pub struct CanMintUserAsset { + pub asset_id: AssetId, + } + } + token! { #[derive(ValidateGrantRevoke, permission::derive_conversions::asset_definition::Owner)] #[validate(permission::asset_definition::Owner)] - pub struct CanTransferAssetsWithDefinition { + pub struct CanTransferAssetWithDefinition { pub asset_definition_id: AssetDefinitionId, } } diff --git a/tools/kagami/src/genesis.rs b/tools/kagami/src/genesis.rs index 6036e4723ab..2e9418ddb8b 100644 --- a/tools/kagami/src/genesis.rs +++ b/tools/kagami/src/genesis.rs @@ -127,21 +127,21 @@ pub fn generate_default(executor: ExecutorMode) -> color_eyre::Result color_eyre::Result