diff --git a/crates/iroha/examples/tutorial.rs b/crates/iroha/examples/tutorial.rs index 75238e76b00..3c4d43aeb79 100644 --- a/crates/iroha/examples/tutorial.rs +++ b/crates/iroha/examples/tutorial.rs @@ -164,7 +164,7 @@ fn asset_registration_test(config: Config) -> Result<(), Error> { // #region register_asset_init_submit // Initialise the registration time let register_time = - Register::asset_definition(AssetDefinition::numeric(asset_def_id.clone()).mintable_once()); + Register::asset_definition(AssetDefinition::new(asset_def_id.clone()).mintable_once()); // Submit a registration time client.submit(register_time)?; diff --git a/crates/iroha/tests/integration/asset.rs b/crates/iroha/tests/integration/asset.rs index e605b0c3432..abd7a5366d8 100644 --- a/crates/iroha/tests/integration/asset.rs +++ b/crates/iroha/tests/integration/asset.rs @@ -3,7 +3,7 @@ use iroha::{ client, crypto::KeyPair, data_model::{ - asset::{AssetId, AssetType, AssetValue}, + asset::AssetId, isi::error::{InstructionEvaluationError, InstructionExecutionError, Mismatch, TypeError}, prelude::*, transaction::error::TransactionRejectionReason, @@ -13,125 +13,25 @@ use iroha_executor_data_model::permission::asset::CanTransferAsset; use iroha_test_network::*; use iroha_test_samples::{gen_account_in, ALICE_ID, BOB_ID}; -#[test] -// This test is also covered at the UI level in the iroha_cli tests -// in test_register_asset_definitions.py -fn client_register_asset_should_add_asset_once_but_not_twice() -> Result<()> { - let (network, _rt) = NetworkBuilder::new().start_blocking()?; - let test_client = network.client(); - - // Given - let account_id = ALICE_ID.clone(); - - let asset_definition_id = "test_asset#wonderland" - .parse::() - .expect("Valid"); - let create_asset = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); - let register_asset = Register::asset(Asset::new( - AssetId::new(asset_definition_id.clone(), account_id.clone()), - 0_u32, - )); - - test_client.submit_all_blocking::([ - create_asset.into(), - register_asset.clone().into(), - ])?; - - // Registering an asset to an account which doesn't have one - // should result in asset being created - let asset = test_client - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(account_id)) - .execute_all()? - .into_iter() - .find(|asset| *asset.id().definition() == asset_definition_id) - .unwrap(); - assert_eq!(*asset.value(), AssetValue::Numeric(Numeric::ZERO)); - - // But registering an asset to account already having one should fail - assert!(test_client.submit_blocking(register_asset).is_err()); - - Ok(()) -} - -#[test] -fn unregister_asset_should_remove_asset_from_account() -> Result<()> { - let (network, _rt) = NetworkBuilder::new().start_blocking()?; - let test_client = network.client(); - - // Given - let account_id = ALICE_ID.clone(); - - let asset_definition_id = "test_asset#wonderland" - .parse::() - .expect("Valid"); - let asset_id = AssetId::new(asset_definition_id.clone(), account_id.clone()); - let create_asset: InstructionBox = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())).into(); - let register_asset = Register::asset(Asset::new(asset_id.clone(), 0_u32)).into(); - let unregister_asset = Unregister::asset(asset_id); - - test_client.submit_all_blocking([create_asset, register_asset])?; - - // Check for asset to be registered - let assets = test_client - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(account_id.clone())) - .execute_all()?; - - assert!(assets - .iter() - .any(|asset| *asset.id().definition() == asset_definition_id)); - - test_client.submit_blocking(unregister_asset)?; - - // ... and check that it is removed after Unregister - let assets = test_client - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(account_id.clone())) - .execute_all()?; - - assert!(assets - .iter() - .all(|asset| *asset.id().definition() != asset_definition_id)); - - Ok(()) -} - #[test] // This test is also covered at the UI level in the iroha_cli tests // in test_mint_assets.py -fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount() -> Result<()> { +fn mint_asset_should_increase_asset_amount() -> Result<()> { let (network, _rt) = NetworkBuilder::new().start_blocking()?; let test_client = network.client(); - // Given - let account_id = ALICE_ID.clone(); - let asset_definition_id = "xor#wonderland" - .parse::() - .expect("Valid"); - let create_asset = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); - let metadata = iroha::data_model::metadata::Metadata::default(); + let account = ALICE_ID.clone(); + let asset_definition = "xor#wonderland".parse::()?; + let define_asset = Register::asset_definition(AssetDefinition::new(asset_definition.clone())); //When + let asset_id = AssetId::new(asset_definition.clone(), account.clone()); let quantity = numeric!(200); - let mint = Mint::asset_numeric( + let mint = Mint::asset_numeric(quantity, asset_id.clone()); + test_client.submit_all_blocking::([define_asset.into(), mint.into()])?; + assert_eq!( quantity, - AssetId::new(asset_definition_id.clone(), account_id.clone()), + test_client.query_single(FindAssetQuantityById::new(asset_id))? ); - let instructions: [InstructionBox; 2] = [create_asset.into(), mint.into()]; - let tx = test_client.build_transaction(instructions, metadata); - test_client.submit_transaction_blocking(&tx)?; - - let asset = test_client - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(account_id)) - .execute_all()? - .into_iter() - .find(|asset| *asset.id().definition() == asset_definition_id) - .unwrap(); - assert_eq!(*asset.value(), AssetValue::Numeric(quantity)); Ok(()) } @@ -141,31 +41,18 @@ fn client_add_big_asset_quantity_to_existing_asset_should_increase_asset_amount( let test_client = network.client(); // Given - let account_id = ALICE_ID.clone(); - let asset_definition_id = "xor#wonderland" - .parse::() - .expect("Valid"); - let create_asset = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); - let metadata = iroha::data_model::metadata::Metadata::default(); - // When + let account = ALICE_ID.clone(); + let asset_definition = "xor#wonderland".parse::()?; + let create_asset = Register::asset_definition(AssetDefinition::new(asset_definition.clone())); + //When let quantity = Numeric::new(2_u128.pow(65), 0); - let mint = Mint::asset_numeric( + let asset_id = AssetId::new(asset_definition, account); + let mint = Mint::asset_numeric(quantity, asset_id.clone()); + test_client.submit_all_blocking::([create_asset.into(), mint.into()])?; + assert_eq!( quantity, - AssetId::new(asset_definition_id.clone(), account_id.clone()), + test_client.query_single(FindAssetQuantityById::new(asset_id))? ); - let instructions: [InstructionBox; 2] = [create_asset.into(), mint.into()]; - let tx = test_client.build_transaction(instructions, metadata); - test_client.submit_transaction_blocking(&tx)?; - - let asset = test_client - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(account_id)) - .execute_all()? - .into_iter() - .find(|asset| *asset.id().definition() == asset_definition_id) - .unwrap(); - assert_eq!(*asset.value(), AssetValue::Numeric(quantity)); Ok(()) } @@ -175,54 +62,31 @@ fn client_add_asset_with_decimal_should_increase_asset_amount() -> Result<()> { let test_client = network.client(); // Given - let account_id = ALICE_ID.clone(); - let asset_definition_id = "xor#wonderland" - .parse::() - .expect("Valid"); - let asset_definition = AssetDefinition::numeric(asset_definition_id.clone()); - let create_asset = Register::asset_definition(asset_definition); - let metadata = iroha::data_model::metadata::Metadata::default(); + let account = ALICE_ID.clone(); + let asset_definition = "xor#wonderland".parse::()?; + let define_asset = Register::asset_definition(AssetDefinition::new(asset_definition.clone())); //When let quantity = numeric!(123.456); - let mint = Mint::asset_numeric( - quantity, - AssetId::new(asset_definition_id.clone(), account_id.clone()), - ); - let instructions: [InstructionBox; 2] = [create_asset.into(), mint.into()]; - let tx = test_client.build_transaction(instructions, metadata); - test_client.submit_transaction_blocking(&tx)?; - - let asset = test_client - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(account_id.clone())) - .execute_all()? - .into_iter() - .find(|asset| *asset.id().definition() == asset_definition_id) - .unwrap(); - assert_eq!(*asset.value(), AssetValue::Numeric(quantity)); + let asset_id = AssetId::new(asset_definition.clone(), account.clone()); + let mint = Mint::asset_numeric(quantity, asset_id.clone()); + test_client + .submit_all_blocking::([define_asset.into(), mint.clone().into()])?; + { + let value = test_client.query_single(FindAssetQuantityById::new(asset_id.clone()))?; + assert_eq!(value, quantity) + } // Add some fractional part - let quantity2 = numeric!(0.55); - let mint = Mint::asset_numeric( - quantity2, - AssetId::new(asset_definition_id.clone(), account_id.clone()), - ); - // and check that it is added without errors - let sum = quantity - .checked_add(quantity2) - .ok_or_else(|| eyre::eyre!("overflow"))?; + let incremint = numeric!(0.55); + let mint = Mint::asset_numeric(incremint, asset_id.clone()); test_client.submit_blocking(mint)?; - - let asset = test_client - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(account_id)) - .execute_all()? - .into_iter() - .find(|asset| *asset.id().definition() == asset_definition_id) - .unwrap(); - assert_eq!(*asset.value(), AssetValue::Numeric(sum)); - + // and check that it is added without errors + let sum = quantity.checked_add(incremint).unwrap(); + { + let value = test_client.query_single(FindAssetQuantityById::new(asset_id.clone()))?; + assert_eq!(value, sum) + } Ok(()) } @@ -333,7 +197,7 @@ fn transfer_asset_definition() { let asset_definition_id: AssetDefinitionId = "asset#wonderland".parse().expect("Valid"); test_client - .submit_blocking(Register::asset_definition(AssetDefinition::numeric( + .submit_blocking(Register::asset_definition(AssetDefinition::new( asset_definition_id.clone(), ))) .expect("Failed to submit transaction"); @@ -371,10 +235,8 @@ fn fail_if_dont_satisfy_spec() { let asset_definition_id: AssetDefinitionId = "asset#wonderland".parse().expect("Valid"); let asset_id: AssetId = AssetId::new(asset_definition_id.clone(), alice_id.clone()); // Create asset definition which accepts only integers - let asset_definition = AssetDefinition::new( - asset_definition_id.clone(), - AssetType::Numeric(NumericSpec::integer()), - ); + let asset_definition = + AssetDefinition::new(asset_definition_id).with_numeric_spec(NumericSpec::integer()); test_client .submit_blocking(Register::asset_definition(asset_definition)) @@ -382,7 +244,7 @@ fn fail_if_dont_satisfy_spec() { let isi = |value: Numeric| { [ - Register::asset(Asset::new(asset_id.clone(), value)).into(), + Mint::asset_numeric(value, asset_id.clone()).into(), Mint::asset_numeric(value, asset_id.clone()).into(), Burn::asset_numeric(value, asset_id.clone()).into(), Transfer::asset_numeric(asset_id.clone(), value, bob_id.clone()).into(), @@ -406,8 +268,8 @@ fn fail_if_dont_satisfy_spec() { &TransactionRejectionReason::Validation(ValidationFail::InstructionFailed( InstructionExecutionError::Evaluate(InstructionEvaluationError::Type( TypeError::from(Mismatch { - expected: AssetType::Numeric(NumericSpec::integer()), - actual: AssetType::Numeric(NumericSpec::fractional(2)) + expected: NumericSpec::integer(), + actual: NumericSpec::fractional(2) }) )) )) @@ -436,7 +298,7 @@ mod register { } pub fn asset_definition_numeric(id: &str) -> Register { - Register::asset_definition(AssetDefinition::numeric( + Register::asset_definition(AssetDefinition::new( id.parse().expect("should parse to AssetDefinitionId"), )) } diff --git a/crates/iroha/tests/integration/asset_propagation.rs b/crates/iroha/tests/integration/asset_propagation.rs index 342152e2dcc..9a44c930536 100644 --- a/crates/iroha/tests/integration/asset_propagation.rs +++ b/crates/iroha/tests/integration/asset_propagation.rs @@ -28,7 +28,7 @@ fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount_on_a let create_account = Register::account(Account::new(account_id.clone())); let asset_definition_id = "xor#domain".parse::()?; let create_asset = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); + Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())); peer_a.client().submit_all_blocking::([ create_domain.into(), create_account.into(), @@ -52,7 +52,6 @@ fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount_on_a .into_iter() .find(|asset| *asset.id().definition() == asset_definition_id) .expect("should be"); - assert_eq!(*asset.value(), AssetValue::Numeric(quantity)); - + assert_eq!(*asset.value(), quantity); Ok(()) } diff --git a/crates/iroha/tests/integration/extra_functional/multiple_blocks_created.rs b/crates/iroha/tests/integration/extra_functional/multiple_blocks_created.rs index b5335e1af58..1489acaa706 100644 --- a/crates/iroha/tests/integration/extra_functional/multiple_blocks_created.rs +++ b/crates/iroha/tests/integration/extra_functional/multiple_blocks_created.rs @@ -41,7 +41,7 @@ async fn multiple_blocks_created() -> Result<()> { let create_account = Register::account(Account::new(account_id.clone())); let asset_definition_id: AssetDefinitionId = "xor#domain".parse()?; let create_asset = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); + Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())); { let client = network.client(); @@ -89,10 +89,9 @@ async fn multiple_blocks_created() -> Result<()> { // ensuring all have the same total sleep(Duration::from_secs(2)).await; println!("all peers should have total={total}"); - let expected_value = AssetValue::Numeric(Numeric::new(total, 0)); + let expected_value = Numeric::new(total, 0); for peer in network.peers() { let client = peer.client(); - let expected_value = expected_value.clone(); let account_id = account_id.clone(); let definition = asset_definition_id.clone(); let assets = spawn_blocking(move || { @@ -108,7 +107,6 @@ async fn multiple_blocks_created() -> Result<()> { let asset = assets.into_iter().next().unwrap(); assert_eq!(*asset.value(), expected_value); } - Ok(()) } diff --git a/crates/iroha/tests/integration/extra_functional/normal.rs b/crates/iroha/tests/integration/extra_functional/normal.rs index 09daf1f2d4d..1945370d7e3 100644 --- a/crates/iroha/tests/integration/extra_functional/normal.rs +++ b/crates/iroha/tests/integration/extra_functional/normal.rs @@ -26,7 +26,7 @@ fn transactions_should_be_applied() -> Result<()> { iroha.submit_blocking(create_domain)?; let create_asset = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); + Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())); iroha.submit_blocking(create_asset)?; let create_account = Register::account(Account::new(account_id.clone())); diff --git a/crates/iroha/tests/integration/extra_functional/offline_peers.rs b/crates/iroha/tests/integration/extra_functional/offline_peers.rs index 33344eb66d6..20f4d8f2e23 100644 --- a/crates/iroha/tests/integration/extra_functional/offline_peers.rs +++ b/crates/iroha/tests/integration/extra_functional/offline_peers.rs @@ -52,7 +52,7 @@ async fn genesis_block_is_committed_with_some_offline_peers() -> Result<()> { .iter() .find(|asset| *asset.id().definition() == roses) .ok_or_eyre("asset should be found")?; - assert_eq!(AssetValue::Numeric(alice_has_roses), *asset.value()); + assert_eq!(alice_has_roses, *asset.value()); Ok(()) }) .await??; diff --git a/crates/iroha/tests/integration/extra_functional/restart_peer.rs b/crates/iroha/tests/integration/extra_functional/restart_peer.rs index b6681c4b645..ac1585c1f9f 100644 --- a/crates/iroha/tests/integration/extra_functional/restart_peer.rs +++ b/crates/iroha/tests/integration/extra_functional/restart_peer.rs @@ -9,6 +9,7 @@ use tokio::{task::spawn_blocking, time::timeout}; #[tokio::test] async fn restarted_peer_should_restore_its_state() -> Result<()> { + let account_id = ALICE_ID.clone(); let asset_definition_id = "xor#wonderland".parse::()?; let quantity = numeric!(200); @@ -22,10 +23,8 @@ async fn restarted_peer_should_restore_its_state() -> Result<()> { spawn_blocking(move || { client .submit_all_blocking::([ - Register::asset_definition(AssetDefinition::numeric( - asset_definition_clone.clone(), - )) - .into(), + Register::asset_definition(AssetDefinition::new(asset_definition_clone.clone())) + .into(), Mint::asset_numeric( quantity, AssetId::new(asset_definition_clone, ALICE_ID.clone()), @@ -55,14 +54,13 @@ async fn restarted_peer_should_restore_its_state() -> Result<()> { let asset = spawn_blocking(move || { client .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(ALICE_ID.clone())) + .filter_with(|asset| asset.id.account.eq(account_id)) .execute_all() }) .await?? .into_iter() .find(|asset| *asset.id().definition() == asset_definition_id) .expect("Asset not found"); - assert_eq!(AssetValue::Numeric(quantity), *asset.value()); - + assert_eq!(quantity, *asset.value()); Ok(()) } diff --git a/crates/iroha/tests/integration/extra_functional/unregister_peer.rs b/crates/iroha/tests/integration/extra_functional/unregister_peer.rs index 8593b49fa06..8a3d1215480 100644 --- a/crates/iroha/tests/integration/extra_functional/unregister_peer.rs +++ b/crates/iroha/tests/integration/extra_functional/unregister_peer.rs @@ -37,7 +37,7 @@ async fn network_stable_after_add_and_after_remove_peer() -> Result<()> { client.submit_all_blocking::([ Register::domain(Domain::new("domain".parse()?)).into(), Register::account(Account::new(account)).into(), - Register::asset_definition(AssetDefinition::numeric(asset_def)).into(), + Register::asset_definition(AssetDefinition::new(asset_def)).into(), ]) }) .await??; // blocks=2 @@ -107,7 +107,7 @@ async fn find_asset( .find(|asset| asset.id().definition() == asset_definition) .expect("asset should be there"); - assert_matches!(asset.value(), AssetValue::Numeric(quantity) => Ok(*quantity)) + assert_matches!(asset.value(), quantity => Ok(*quantity)) } async fn mint( diff --git a/crates/iroha/tests/integration/multisig.rs b/crates/iroha/tests/integration/multisig.rs index 9d1e82767b3..2a183052ed2 100644 --- a/crates/iroha/tests/integration/multisig.rs +++ b/crates/iroha/tests/integration/multisig.rs @@ -100,10 +100,7 @@ fn mutlisig() -> Result<()> { .parse::() .unwrap(); let isi = - vec![ - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())) - .into(), - ]; + vec![Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())).into()]; let isi_hash = HashOf::new(&isi); let mut signatories_iter = signatories.into_iter(); diff --git a/crates/iroha/tests/integration/non_mintable.rs b/crates/iroha/tests/integration/non_mintable.rs index 15e446e118d..7dce911b3f4 100644 --- a/crates/iroha/tests/integration/non_mintable.rs +++ b/crates/iroha/tests/integration/non_mintable.rs @@ -1,8 +1,5 @@ use eyre::Result; -use iroha::{ - client, - data_model::{isi::InstructionBox, prelude::*}, -}; +use iroha::data_model::{isi::InstructionBox, prelude::*}; use iroha_test_network::*; use iroha_test_samples::ALICE_ID; @@ -17,113 +14,26 @@ fn non_mintable_asset_can_be_minted_once_but_not_twice() -> Result<()> { .parse::() .expect("Valid"); let create_asset = Register::asset_definition( - AssetDefinition::numeric(asset_definition_id.clone()).mintable_once(), + AssetDefinition::new(asset_definition_id.clone()).mintable_once(), ); - let metadata = Metadata::default(); - - let mint = Mint::asset_numeric( - 200_u32, - AssetId::new(asset_definition_id.clone(), account_id.clone()), - ); - - let instructions: [InstructionBox; 2] = [create_asset.into(), mint.clone().into()]; - let tx = test_client.build_transaction(instructions, metadata); + let asset_id = AssetId::new(asset_definition_id.clone(), account_id.clone()); + let mint = Mint::asset_numeric(numeric!(200), asset_id.clone()); // We can register and mint the non-mintable token - test_client.submit_transaction_blocking(&tx)?; - assert!(test_client - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(account_id.clone())) - .execute_all()? - .iter() - .any(|asset| { - *asset.id().definition() == asset_definition_id - && *asset.value() == AssetValue::Numeric(numeric!(200)) - })); - - // We can submit the request to mint again. - // However, this will fail - assert!(test_client.submit_all_blocking([mint]).is_err()); - - Ok(()) -} - -#[test] -fn non_mintable_asset_cannot_be_minted_if_registered_with_non_zero_value() -> Result<()> { - let (network, _rt) = NetworkBuilder::new().start_blocking()?; - let test_client = network.client(); - - // Given - let account_id = ALICE_ID.clone(); - let asset_definition_id = "xor#wonderland" - .parse::() - .expect("Valid"); - let create_asset = Register::asset_definition( - AssetDefinition::numeric(asset_definition_id.clone()).mintable_once(), + test_client + .submit_all_blocking::([create_asset.into(), mint.clone().into()])?; + assert_eq!( + numeric!(200), + test_client.query_single(FindAssetQuantityById::new(asset_id.clone()))? ); - let asset_id = AssetId::new(asset_definition_id.clone(), account_id.clone()); - let register_asset = Register::asset(Asset::new(asset_id.clone(), 1_u32)); - - // We can register the non-mintable token - test_client.submit_all_blocking::([ - create_asset.into(), - register_asset.clone().into(), - ])?; - assert!(test_client - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(account_id.clone())) - .execute_all()? - .iter() - .any(|asset| { - *asset.id().definition() == asset_definition_id - && *asset.value() == AssetValue::Numeric(numeric!(1)) - })); - - // But only once - assert!(test_client.submit_blocking(register_asset).is_err()); - - // And can't be minted - let mint = Mint::asset_numeric(1u32, asset_id); - assert!(test_client.submit_blocking(mint).is_err()); - - Ok(()) -} - -#[test] -fn non_mintable_asset_can_be_minted_if_registered_with_zero_value() -> Result<()> { - let (network, _rt) = NetworkBuilder::new().start_blocking()?; - let test_client = network.client(); - - // Given - let account_id = ALICE_ID.clone(); - let asset_definition_id = "xor#wonderland" - .parse::() - .expect("Valid"); - let create_asset = Register::asset_definition( - AssetDefinition::numeric(asset_definition_id.clone()).mintable_once(), + // We can submit the request to mint again. + test_client.submit(mint)?; + // However, this will fail: + assert_ne!( + numeric!(400), + test_client.query_single(FindAssetQuantityById::new(asset_id))? ); - - let asset_id = AssetId::new(asset_definition_id.clone(), account_id.clone()); - let register_asset = Register::asset(Asset::new(asset_id.clone(), 0_u32)); - let mint = Mint::asset_numeric(1u32, asset_id); - - // We can register the non-mintable token wih zero value and then mint it - test_client.submit_all_blocking::([ - create_asset.into(), - register_asset.into(), - mint.into(), - ])?; - assert!(test_client - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(account_id.clone())) - .execute_all()? - .iter() - .any(|asset| { - *asset.id().definition() == asset_definition_id - && *asset.value() == AssetValue::Numeric(numeric!(1)) - })); - Ok(()) } diff --git a/crates/iroha/tests/integration/pagination.rs b/crates/iroha/tests/integration/pagination.rs index 72eb240afd8..f8d7a38cce7 100644 --- a/crates/iroha/tests/integration/pagination.rs +++ b/crates/iroha/tests/integration/pagination.rs @@ -90,7 +90,7 @@ fn register_assets(client: &Client) -> Result<()> { .map(|c| c.to_string()) .map(|name| (name + "#wonderland").parse().expect("Valid")) .map(|asset_definition_id| { - Register::asset_definition(AssetDefinition::numeric(asset_definition_id)) + Register::asset_definition(AssetDefinition::new(asset_definition_id)) }) .collect(); let _ = client.submit_all_blocking(register)?; diff --git a/crates/iroha/tests/integration/permissions.rs b/crates/iroha/tests/integration/permissions.rs index 3bb8ea0d8a8..de1f5af0718 100644 --- a/crates/iroha/tests/integration/permissions.rs +++ b/crates/iroha/tests/integration/permissions.rs @@ -10,11 +10,11 @@ use iroha::{ }, }; use iroha_executor_data_model::permission::{ - asset::{CanModifyAssetMetadata, CanTransferAsset}, + asset::{CanMintAssetWithDefinition, CanTransferAsset}, domain::CanModifyDomainMetadata, }; use iroha_test_network::*; -use iroha_test_samples::{gen_account_in, ALICE_ID, BOB_ID}; +use iroha_test_samples::{gen_account_in, ALICE_ID, BOB_ID, BOB_KEYPAIR}; use tokio::{join, time::timeout}; #[tokio::test] @@ -22,8 +22,7 @@ async fn genesis_transactions_are_validated_by_executor() { // `wonderland` domain is owned by Alice, // so the default executor will deny a genesis account to register asset definition. let asset_definition_id = "xor#wonderland".parse().expect("Valid"); - let invalid_instruction = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id)); + let invalid_instruction = Register::asset_definition(AssetDefinition::new(asset_definition_id)); let network = NetworkBuilder::new() .with_genesis_instruction(invalid_instruction) .build(); @@ -68,7 +67,7 @@ fn permissions_disallow_asset_transfer() { let (mouse_id, _mouse_keypair) = gen_account_in("wonderland"); let asset_definition_id: AssetDefinitionId = "xor#wonderland".parse().expect("Valid"); let create_asset = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); + Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())); let mouse_keypair = KeyPair::random(); let alice_start_assets = get_assets(&iroha, &alice_id); @@ -124,7 +123,7 @@ fn permissions_disallow_asset_burn() { .parse::() .expect("Valid"); let create_asset = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); + Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())); let mouse_keypair = KeyPair::random(); let alice_start_assets = get_assets(&iroha, &alice_id); @@ -194,94 +193,59 @@ fn account_can_query_only_its_own_domain() -> Result<()> { #[test] fn permissions_differ_not_only_by_names() { - let chain_id = ChainId::from("00000000-0000-0000-0000-000000000000"); - let (network, _rt) = NetworkBuilder::new().start_blocking().unwrap(); let client = network.client(); - let alice_id = ALICE_ID.clone(); - let (mouse_id, mouse_keypair) = gen_account_in("outfit"); - - // Registering mouse - let outfit_domain: DomainId = "outfit".parse().unwrap(); - let create_outfit_domain = Register::domain(Domain::new(outfit_domain.clone())); - let register_mouse_account = Register::account(Account::new(mouse_id.clone())); - client - .submit_all_blocking::([ - create_outfit_domain.into(), - register_mouse_account.into(), - ]) - .expect("Failed to register mouse"); - - // Registering `Store` asset definitions - let hat_definition_id: AssetDefinitionId = "hat#outfit".parse().expect("Valid"); - let register_hat_definition = - Register::asset_definition(AssetDefinition::store(hat_definition_id.clone())); - let transfer_shoes_domain = Transfer::domain(alice_id.clone(), outfit_domain, mouse_id.clone()); - let shoes_definition_id: AssetDefinitionId = "shoes#outfit".parse().expect("Valid"); - let register_shoes_definition = - Register::asset_definition(AssetDefinition::store(shoes_definition_id.clone())); - client - .submit_all_blocking::([ - register_hat_definition.into(), - register_shoes_definition.into(), - transfer_shoes_domain.into(), - ]) - .expect("Failed to register new asset definitions"); - - // Granting permission to Alice to modify metadata in Mouse's hats - let mouse_hat_id = AssetId::new(hat_definition_id, mouse_id.clone()); - let mouse_hat_permission = CanModifyAssetMetadata { - asset: mouse_hat_id.clone(), - }; - let allow_alice_to_set_key_value_in_hats = - Grant::account_permission(mouse_hat_permission, alice_id.clone()); + let alice_in_wland = ALICE_ID.clone(); + let (bob_in_wland, bob_in_wland_key) = (BOB_ID.clone(), BOB_KEYPAIR.private_key()); - let grant_hats_access_tx = TransactionBuilder::new(chain_id.clone(), mouse_id.clone()) - .with_instructions([allow_alice_to_set_key_value_in_hats]) - .sign(mouse_keypair.private_key()); + let wland_roses = "rose#wonderland".parse::().unwrap(); + let wland_coins = "coin#wonderland".parse::().unwrap(); client - .submit_transaction_blocking(&grant_hats_access_tx) - .expect("Failed grant permission to modify Mouse's hats"); + .submit_blocking(Register::asset_definition(AssetDefinition::new( + wland_coins.clone(), + ))) + .unwrap(); - // Checking that Alice can modify Mouse's hats ... + // allow Bob to mint roses client - .submit_blocking(SetKeyValue::asset( - mouse_hat_id, - "color".parse().expect("Valid"), - "red".parse::().expect("Valid"), + .submit_blocking(Grant::account_permission( + CanMintAssetWithDefinition { + asset_definition: wland_roses.clone(), + }, + bob_in_wland.clone(), )) - .expect("Failed to modify Mouse's hats"); - - // ... but not shoes - let mouse_shoes_id = AssetId::new(shoes_definition_id, mouse_id.clone()); - let set_shoes_color = SetKeyValue::asset( - mouse_shoes_id.clone(), - "color".parse().expect("Valid"), - "yellow".parse::().expect("Valid"), - ); - let _err = client - .submit_blocking(set_shoes_color.clone()) - .expect_err("Expected Alice to fail to modify Mouse's shoes"); - - let mouse_shoes_permission = CanModifyAssetMetadata { - asset: mouse_shoes_id, - }; - let allow_alice_to_set_key_value_in_shoes = - Grant::account_permission(mouse_shoes_permission, alice_id); - - let grant_shoes_access_tx = TransactionBuilder::new(chain_id, mouse_id) - .with_instructions([allow_alice_to_set_key_value_in_shoes]) - .sign(mouse_keypair.private_key()); - + .unwrap(); + // check that Bob can mint roses + let wland_roses_of_alice = AssetId::new(wland_roses, alice_in_wland.clone()); + let wland_coins_of_alice = AssetId::new(wland_coins.clone(), alice_in_wland.clone()); client - .submit_transaction_blocking(&grant_shoes_access_tx) - .expect("Failed grant permission to modify Mouse's shoes"); - - // Checking that Alice can modify Mouse's shoes + .submit_blocking(Mint::asset_numeric(1_u32, wland_roses_of_alice)) + .unwrap(); + // check that Bob cannot mint coins + // FIXME: sign transaction as Bob + let chain_id = ChainId::from("00000000-0000-0000-0000-000000000000"); + let tx = TransactionBuilder::new(chain_id.clone(), bob_in_wland.clone()) + .with_instructions(Some(Mint::asset_numeric( + 1_u32, + wland_coins_of_alice.clone(), + ))) + .sign(bob_in_wland_key); + let _ = client.submit_transaction_blocking(&tx).unwrap_err(); + // allow Bob to mint coins client - .submit_blocking(set_shoes_color) - .expect("Failed to modify Mouse's shoes"); + .submit_blocking(Grant::account_permission( + CanMintAssetWithDefinition { + asset_definition: wland_coins.clone(), + }, + bob_in_wland.clone(), + )) + .unwrap(); + // check that Bob can mint coins + let tx = TransactionBuilder::new(chain_id, bob_in_wland) + .with_instructions(Some(Mint::asset_numeric(1_u32, wland_coins_of_alice))) + .sign(bob_in_wland_key); + client.submit_transaction_blocking(&tx).unwrap(); } #[test] @@ -295,14 +259,15 @@ fn stored_vs_granted_permission_payload() -> Result<()> { let alice_id = ALICE_ID.clone(); // Registering mouse and asset definition - let asset_definition_id: AssetDefinitionId = "xor#wonderland".parse().expect("Valid"); + let asset_definition_id: AssetDefinitionId = "xor#wonderland".parse()?; let create_asset = - Register::asset_definition(AssetDefinition::store(asset_definition_id.clone())); + Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())); let (mouse_id, mouse_keypair) = gen_account_in("wonderland"); let register_mouse_account = Register::account(Account::new(mouse_id.clone())); - iroha - .submit_all_blocking::([register_mouse_account.into(), create_asset.into()]) - .expect("Failed to register mouse"); + iroha.submit_all_blocking::([ + register_mouse_account.into(), + create_asset.into(), + ])?; // Allow alice to mint mouse asset and mint initial value let value_json = Json::from_string_unchecked(format!( @@ -312,27 +277,19 @@ fn stored_vs_granted_permission_payload() -> Result<()> { )); let mouse_asset = AssetId::new(asset_definition_id, mouse_id.clone()); - let allow_alice_to_set_key_value_in_mouse_asset = Grant::account_permission( - Permission::new("CanModifyAssetMetadata".parse().unwrap(), value_json), + let allow_alice_to_mint_mouse_asset = Grant::account_permission( + Permission::new("CanMintAsset".parse()?, value_json), alice_id, ); let transaction = TransactionBuilder::new(chain_id, mouse_id) - .with_instructions([allow_alice_to_set_key_value_in_mouse_asset]) + .with_instructions([allow_alice_to_mint_mouse_asset]) .sign(mouse_keypair.private_key()); - iroha - .submit_transaction_blocking(&transaction) - .expect("Failed to grant permission to alice."); + iroha.submit_transaction_blocking(&transaction)?; // Check that alice can indeed mint mouse asset - let set_key_value = SetKeyValue::asset( - mouse_asset, - "color".parse()?, - "red".parse::().expect("Valid"), - ); - iroha - .submit_blocking(set_key_value) - .expect("Failed to mint asset for mouse."); + let set_key_value = Mint::asset_numeric(1_u32, mouse_asset); + iroha.submit_blocking(set_key_value)?; Ok(()) } diff --git a/crates/iroha/tests/integration/queries/account.rs b/crates/iroha/tests/integration/queries/account.rs index cb9327ecc9d..7b0a6634e0b 100644 --- a/crates/iroha/tests/integration/queries/account.rs +++ b/crates/iroha/tests/integration/queries/account.rs @@ -14,7 +14,7 @@ fn find_accounts_with_asset() -> Result<()> { let definition_id = "test_coin#wonderland" .parse::() .expect("Valid"); - let asset_definition = AssetDefinition::numeric(definition_id.clone()); + let asset_definition = AssetDefinition::new(definition_id.clone()); test_client.submit_blocking(Register::asset_definition(asset_definition.clone()))?; // Checking results before all @@ -24,10 +24,6 @@ fn find_accounts_with_asset() -> Result<()> { .execute_single()?; assert_eq!(received_asset_definition.id(), asset_definition.id()); - assert!(matches!( - received_asset_definition.type_(), - AssetType::Numeric(_) - )); let accounts: [AccountId; 5] = [ ALICE_ID.clone(), @@ -63,10 +59,7 @@ fn find_accounts_with_asset() -> Result<()> { .execute_single()?; assert_eq!(received_asset_definition.id(), asset_definition.id()); - assert_eq!( - received_asset_definition.type_(), - AssetType::Numeric(NumericSpec::default()), - ); + assert_eq!(received_asset_definition.spec(), NumericSpec::default(),); let found_accounts = test_client .query(client::account::all_with_asset(definition_id)) diff --git a/crates/iroha/tests/integration/queries/asset.rs b/crates/iroha/tests/integration/queries/asset.rs index a249df880cb..9aad55fc285 100644 --- a/crates/iroha/tests/integration/queries/asset.rs +++ b/crates/iroha/tests/integration/queries/asset.rs @@ -1,9 +1,7 @@ use eyre::Result; use iroha::{ client::{Client, QueryError}, - data_model::{ - asset::AssetValue, isi::Instruction, prelude::*, query::builder::SingleQueryError, - }, + data_model::{isi::Instruction, prelude::*, query::builder::SingleQueryError}, }; use iroha_test_network::*; use iroha_test_samples::{gen_account_in, ALICE_ID}; @@ -41,11 +39,9 @@ fn find_asset_total_quantity() -> Result<()> { &test_client, &accounts, "quantity#wonderland", - AssetType::Numeric(NumericSpec::default()), - numeric!(1), numeric!(10), numeric!(5), - numeric!(30), + numeric!(25), Mint::asset_numeric, Burn::asset_numeric, )?; @@ -53,94 +49,36 @@ fn find_asset_total_quantity() -> Result<()> { &test_client, &accounts, "fixed#wonderland", - AssetType::Numeric(NumericSpec::default()), - numeric!(1.0), numeric!(10.0), numeric!(5.0), - numeric!(30.0), + numeric!(25.0), Mint::asset_numeric, Burn::asset_numeric, )?; - - // Test for `Store` asset value type - let definition_id: AssetDefinitionId = "store#wonderland".parse().expect("Valid"); - let asset_definition = AssetDefinition::store(definition_id.clone()); - test_client.submit_blocking(Register::asset_definition(asset_definition))?; - - let asset_ids = accounts - .iter() - .cloned() - .map(|account_id| AssetId::new(definition_id.clone(), account_id)) - .collect::>(); - - let get_quantity = || -> Result> { - Ok(test_client - .query(FindAssetsDefinitions::new()) - .filter_with(|asset_definition| asset_definition.id.eq(definition_id.clone())) - .execute_single()? - .total_quantity) - }; - - // Assert that initial total quantity before any registrations and unregistrations is zero - let initial_total_asset_quantity = get_quantity()?; - - assert!(initial_total_asset_quantity.is_zero()); - - let register_assets = asset_ids - .iter() - .cloned() - .map(|asset_id| Asset::new(asset_id, Metadata::default())) - .map(Register::asset) - .collect::>(); - test_client.submit_all_blocking(register_assets)?; - - // Assert that total quantity is equal to number of registrations - let result = get_quantity()?; - assert_eq!(numeric!(5), result); - - let unregister_assets = asset_ids - .iter() - .cloned() - .map(Unregister::asset) - .collect::>(); - test_client.submit_all_blocking(unregister_assets)?; - - // Assert that total asset quantity is zero after unregistering asset from all accounts - let total_asset_quantity = get_quantity()?; - assert!(total_asset_quantity.is_zero()); - - // Unregister asset definition - test_client.submit_blocking(Unregister::asset_definition(definition_id.clone()))?; - - // Assert that total asset quantity cleared with unregistering of asset definition - let result = get_quantity(); - assert!(matches!(result, Err(SingleQueryError::ExpectedOneGotNone))); - Ok(()) } +// TODO: re-add store asset test + #[allow(clippy::too_many_arguments)] -fn test_total_quantity( +fn test_total_quantity( test_client: &Client, accounts: &[AccountId; 5], definition: &str, - asset_type: AssetType, - initial_value: T, - to_mint: T, - to_burn: T, + to_mint: Numeric, + to_burn: Numeric, expected_total_asset_quantity: Numeric, - mint_ctr: impl Fn(T, AssetId) -> Mint, - burn_ctr: impl Fn(T, AssetId) -> Burn, + mint_ctr: impl Fn(Numeric, AssetId) -> Mint, + burn_ctr: impl Fn(Numeric, AssetId) -> Burn, ) -> Result<()> where - T: Copy + Into, - Mint: Instruction, - Burn: Instruction, + Mint: Instruction, + Burn: Instruction, { // Registering new asset definition let definition_id: AssetDefinitionId = definition.parse().expect("Failed to parse `definition_id`"); - let asset_definition = AssetDefinition::new(definition_id.clone(), asset_type); + let asset_definition = AssetDefinition::new(definition_id.clone()); test_client.submit_blocking(Register::asset_definition(asset_definition))?; let asset_ids = accounts @@ -161,14 +99,6 @@ where let initial_total_asset_quantity = get_quantity()?; assert!(initial_total_asset_quantity.is_zero()); - let register_assets = asset_ids - .iter() - .cloned() - .map(|asset_id| Asset::new(asset_id, initial_value)) - .map(Register::asset) - .collect::>(); - test_client.submit_all_blocking(register_assets)?; - let mint_assets = asset_ids .iter() .cloned() @@ -182,21 +112,10 @@ where .collect::>(); test_client.submit_all_blocking(burn_assets)?; - // Assert that total asset quantity is equal to: `n_accounts * (initial_value + to_mint - to_burn)` + // Assert that total asset quantity is equal to: `n_accounts * (to_mint - to_burn)` let total_asset_quantity = get_quantity()?; assert_eq!(expected_total_asset_quantity, total_asset_quantity); - let unregister_assets = asset_ids - .iter() - .cloned() - .map(Unregister::asset) - .collect::>(); - test_client.submit_all_blocking(unregister_assets)?; - - // Assert that total asset quantity is zero after unregistering asset from all accounts - let total_asset_quantity = get_quantity()?; - assert!(total_asset_quantity.is_zero()); - // Unregister asset definition test_client.submit_blocking(Unregister::asset_definition(definition_id.clone()))?; diff --git a/crates/iroha/tests/integration/sorting.rs b/crates/iroha/tests/integration/sorting.rs index 3bf941afcd5..6ac3443584e 100644 --- a/crates/iroha/tests/integration/sorting.rs +++ b/crates/iroha/tests/integration/sorting.rs @@ -4,117 +4,111 @@ use eyre::{Result, WrapErr as _}; use iroha::{ client::{self, QueryResult}, crypto::KeyPair, - data_model::{ - account::Account, name::Name, prelude::*, - query::predicate::predicate_atoms::asset::AssetPredicateBox, - }, + data_model::{account::Account, name::Name, prelude::*}, }; use iroha_test_network::*; -use iroha_test_samples::ALICE_ID; -use nonzero_ext::nonzero; -use rand::{seq::SliceRandom, thread_rng}; #[test] #[ignore] #[allow(clippy::cast_possible_truncation)] fn correct_pagination_assets_after_creating_new_one() { // FIXME transaction is rejected for more than a certain number of instructions - const N_ASSETS: usize = 12; - // 0 < pagination.start < missing_idx < pagination.end < N_ASSETS - let missing_indices = vec![N_ASSETS / 2]; - let pagination = Pagination { - limit: Some(nonzero!(N_ASSETS as u64 / 3)), - offset: N_ASSETS as u64 / 3, - }; - let xor_filter = - AssetPredicateBox::build(|asset| asset.id.definition_id.name.starts_with("xor")); - - let sort_by_metadata_key = "sort".parse::().expect("Valid"); - let sorting = Sorting::by_metadata_key(sort_by_metadata_key.clone()); - let account_id = ALICE_ID.clone(); - - let (network, _rt) = NetworkBuilder::new().start_blocking().unwrap(); - let test_client = network.client(); - - let mut tester_assets = vec![]; - let mut register_asset_definitions = vec![]; - let mut register_assets = vec![]; - - let mut missing_tester_assets = vec![]; - let mut missing_register_asset_definitions = vec![]; - let mut missing_register_assets = vec![]; - - for i in 0..N_ASSETS { - let asset_definition_id = format!("xor{i}#wonderland") - .parse::() - .expect("Valid"); - let asset_definition = AssetDefinition::store(asset_definition_id.clone()); - let mut asset_metadata = Metadata::default(); - asset_metadata.insert(sort_by_metadata_key.clone(), i as u32); - let asset = Asset::new( - AssetId::new(asset_definition_id, account_id.clone()), - AssetValue::Store(asset_metadata), - ); - - if missing_indices.contains(&i) { - missing_tester_assets.push(asset.clone()); - missing_register_asset_definitions.push(Register::asset_definition(asset_definition)); - missing_register_assets.push(Register::asset(asset)); - } else { - tester_assets.push(asset.clone()); - register_asset_definitions.push(Register::asset_definition(asset_definition)); - register_assets.push(Register::asset(asset)); - } - } - register_asset_definitions.shuffle(&mut thread_rng()); - register_assets.shuffle(&mut thread_rng()); - - test_client - .submit_all_blocking(register_asset_definitions) - .expect("Valid"); - test_client - .submit_all_blocking(register_assets) - .expect("Valid"); - - let queried_assets = test_client - .query(client::asset::all()) - .filter(xor_filter.clone()) - .with_pagination(pagination) - .with_sorting(sorting.clone()) - .execute_all() - .expect("Valid"); - - tester_assets - .iter() - .skip(N_ASSETS / 3) - .take(N_ASSETS / 3) - .zip(queried_assets) - .for_each(|(tester, queried)| assert_eq!(*tester, queried)); - - for (i, missing_idx) in missing_indices.into_iter().enumerate() { - tester_assets.insert(missing_idx, missing_tester_assets[i].clone()); - } - test_client - .submit_all_blocking(missing_register_asset_definitions) - .expect("Valid"); - test_client - .submit_all_blocking(missing_register_assets) - .expect("Valid"); - - let queried_assets = test_client - .query(client::asset::all()) - .filter(xor_filter) - .with_pagination(pagination) - .with_sorting(sorting) - .execute_all() - .expect("Valid"); - - tester_assets - .iter() - .skip(N_ASSETS / 3) - .take(N_ASSETS / 3) - .zip(queried_assets) - .for_each(|(tester, queried)| assert_eq!(*tester, queried)); + // const N_ASSETS: usize = 12; + // // 0 < pagination.start < missing_idx < pagination.end < N_ASSETS + // let missing_indices = vec![N_ASSETS / 2]; + // let pagination = Pagination { + // limit: Some(nonzero!(N_ASSETS as u64 / 3)), + // offset: N_ASSETS as u64 / 3, + // }; + // let xor_filter = + // AssetPredicateBox::build(|asset| asset.id.definition_id.name.starts_with("xor")); + // + // let sort_by_metadata_key = "sort".parse::().expect("Valid"); + // let sorting = Sorting::by_metadata_key(sort_by_metadata_key.clone()); + // let account_id = ALICE_ID.clone(); + // + // let (network, _rt) = NetworkBuilder::new().start_blocking().unwrap(); + // let test_client = network.client(); + // + // let mut tester_assets = vec![]; + // let mut register_asset_definitions = vec![]; + // let mut register_assets = vec![]; + // + // let mut missing_tester_assets = vec![]; + // let mut missing_register_asset_definitions = vec![]; + // let mut missing_register_assets = vec![]; + // + // for i in 0..N_ASSETS { + // let asset_definition_id = format!("xor{i}#wonderland") + // .parse::() + // .expect("Valid"); + // let asset_definition = AssetDefinition::store(asset_definition_id.clone()); + // let mut asset_metadata = Metadata::default(); + // asset_metadata.insert(sort_by_metadata_key.clone(), i as u32); + // let asset = Asset::new( + // AssetId::new(asset_definition_id, account_id.clone()), + // AssetValue::Store(asset_metadata), + // ); + // + // if missing_indices.contains(&i) { + // missing_tester_assets.push(asset.clone()); + // missing_register_asset_definitions.push(Register::asset_definition(asset_definition)); + // missing_register_assets.push(Register::asset(asset)); + // } else { + // tester_assets.push(asset.clone()); + // register_asset_definitions.push(Register::asset_definition(asset_definition)); + // register_assets.push(Register::asset(asset)); + // } + // } + // register_asset_definitions.shuffle(&mut thread_rng()); + // register_assets.shuffle(&mut thread_rng()); + // + // test_client + // .submit_all_blocking(register_asset_definitions) + // .expect("Valid"); + // test_client + // .submit_all_blocking(register_assets) + // .expect("Valid"); + // + // let queried_assets = test_client + // .query(client::asset::all()) + // .filter(xor_filter.clone()) + // .with_pagination(pagination) + // .with_sorting(sorting.clone()) + // .execute_all() + // .expect("Valid"); + // + // tester_assets + // .iter() + // .skip(N_ASSETS / 3) + // .take(N_ASSETS / 3) + // .zip(queried_assets) + // .for_each(|(tester, queried)| assert_eq!(*tester, queried)); + // + // for (i, missing_idx) in missing_indices.into_iter().enumerate() { + // tester_assets.insert(missing_idx, missing_tester_assets[i].clone()); + // } + // test_client + // .submit_all_blocking(missing_register_asset_definitions) + // .expect("Valid"); + // test_client + // .submit_all_blocking(missing_register_assets) + // .expect("Valid"); + // + // let queried_assets = test_client + // .query(client::asset::all()) + // .filter(xor_filter) + // .with_pagination(pagination) + // .with_sorting(sorting) + // .execute_all() + // .expect("Valid"); + // + // tester_assets + // .iter() + // .skip(N_ASSETS / 3) + // .take(N_ASSETS / 3) + // .zip(queried_assets) + // .for_each(|(tester, queried)| assert_eq!(*tester, queried)); } #[test] @@ -137,8 +131,8 @@ fn correct_sorting_of_entities() { .expect("Valid"); let mut asset_metadata = Metadata::default(); asset_metadata.insert(sort_by_metadata_key.clone(), n - i - 1); - let asset_definition = AssetDefinition::numeric(asset_definition_id.clone()) - .with_metadata(asset_metadata.clone()); + let asset_definition = + AssetDefinition::new(asset_definition_id.clone()).with_metadata(asset_metadata.clone()); metadata_of_assets.push(asset_metadata); asset_definitions.push(asset_definition_id); diff --git a/crates/iroha/tests/integration/transfer_asset.rs b/crates/iroha/tests/integration/transfer_asset.rs index aed42d95995..ed90e9e71d4 100644 --- a/crates/iroha/tests/integration/transfer_asset.rs +++ b/crates/iroha/tests/integration/transfer_asset.rs @@ -2,10 +2,8 @@ use iroha::{ client, data_model::{ account::{Account, AccountId}, - asset::{Asset, AssetDefinition}, - isi::{Instruction, InstructionBox}, + isi::InstructionBox, prelude::*, - Registered, }, }; use iroha_test_network::*; @@ -15,17 +13,10 @@ use iroha_test_samples::{gen_account_in, ALICE_ID}; // This test suite is also covered at the UI level in the iroha_cli tests // in test_tranfer_assets.py fn simulate_transfer_numeric() { - simulate_transfer( - numeric!(200), - &numeric!(20), - AssetDefinition::numeric, - Mint::asset_numeric, - Transfer::asset_numeric, - ) + simulate_transfer(numeric!(200), numeric!(20)) } -#[test] -fn simulate_transfer_store_asset() { +fn simulate_transfer(starting_amount: Numeric, amount_to_transfer: Numeric) { let (network, _rt) = NetworkBuilder::new().start_blocking().unwrap(); let iroha = network.client(); @@ -33,79 +24,25 @@ fn simulate_transfer_store_asset() { let create_mouse = create_mouse(mouse_id.clone()); let asset_definition_id: AssetDefinitionId = "camomile#wonderland".parse().unwrap(); let create_asset = - Register::asset_definition(AssetDefinition::store(asset_definition_id.clone())); - let set_key_value = SetKeyValue::asset( + Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())); + let mint_asset = Mint::asset_numeric( + starting_amount, AssetId::new(asset_definition_id.clone(), alice_id.clone()), - "alicek".parse().unwrap(), - true, ); iroha .submit_all_blocking::([ - // create_alice.into(), We don't need to register Alice, because she is created in genesis + // We don't need to register Alice, because she is created in genesis create_mouse.into(), create_asset.into(), - set_key_value.into(), + mint_asset.into(), ]) .expect("Failed to prepare state."); - let transfer_asset = Transfer::asset_store( - AssetId::new(asset_definition_id.clone(), alice_id.clone()), - mouse_id.clone(), - ); - - iroha - .submit_blocking(transfer_asset) - .expect("Failed to transfer asset."); - assert!(iroha - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(mouse_id.clone())) - .execute_all() - .unwrap() - .into_iter() - .any(|asset| { - *asset.id().definition() == asset_definition_id && *asset.id().account() == mouse_id - })); -} - -fn simulate_transfer( - starting_amount: T, - amount_to_transfer: &T, - asset_definition_ctr: impl FnOnce(AssetDefinitionId) -> ::With, - mint_ctr: impl FnOnce(T, AssetId) -> Mint, - transfer_ctr: impl FnOnce(AssetId, T, AccountId) -> Transfer, -) where - T: std::fmt::Debug + Clone + Into, - Mint: Instruction, - Transfer: Instruction, -{ - let (network, _rt) = NetworkBuilder::new().start_blocking().unwrap(); - let iroha = network.client(); - - let (alice_id, mouse_id) = generate_two_ids(); - let create_mouse = create_mouse(mouse_id.clone()); - let asset_definition_id: AssetDefinitionId = "camomile#wonderland".parse().unwrap(); - let create_asset = - Register::asset_definition(asset_definition_ctr(asset_definition_id.clone())); - let mint_asset = mint_ctr( - starting_amount, - AssetId::new(asset_definition_id.clone(), alice_id.clone()), - ); - - let instructions: [InstructionBox; 3] = [ - // create_alice.into(), We don't need to register Alice, because she is created in genesis - create_mouse.into(), - create_asset.into(), - mint_asset.into(), - ]; - iroha - .submit_all_blocking(instructions) - .expect("Failed to prepare state."); - //When - let transfer_asset = transfer_ctr( + let transfer_asset = Transfer::asset_numeric( AssetId::new(asset_definition_id.clone(), alice_id), - amount_to_transfer.clone(), + amount_to_transfer, mouse_id.clone(), ); iroha @@ -119,7 +56,7 @@ fn simulate_transfer( .into_iter() .any(|asset| { *asset.id().definition() == asset_definition_id - && *asset.value() == amount_to_transfer.clone().into() + && *asset.value() == amount_to_transfer && *asset.id().account() == mouse_id })); } diff --git a/crates/iroha/tests/integration/transfer_domain.rs b/crates/iroha/tests/integration/transfer_domain.rs index 414346bacd2..a82f6c82986 100644 --- a/crates/iroha/tests/integration/transfer_domain.rs +++ b/crates/iroha/tests/integration/transfer_domain.rs @@ -6,7 +6,7 @@ use iroha::{ }; use iroha_executor_data_model::permission::{ account::CanUnregisterAccount, - asset::CanUnregisterAsset, + asset::CanMintAsset, asset_definition::{CanRegisterAssetDefinition, CanUnregisterAssetDefinition}, domain::CanUnregisterDomain, trigger::CanUnregisterTrigger, @@ -23,7 +23,7 @@ fn domain_owner_domain_permissions() -> Result<()> { let kingdom_id: DomainId = "kingdom".parse()?; let (bob_id, bob_keypair) = gen_account_in("kingdom"); let coin_id: AssetDefinitionId = "coin#kingdom".parse()?; - let coin = AssetDefinition::numeric(coin_id.clone()); + let coin = AssetDefinition::new(coin_id.clone()); // "alice@wonderland" is owner of "kingdom" domain let kingdom = Domain::new(kingdom_id.clone()); @@ -156,7 +156,7 @@ fn domain_owner_asset_definition_permissions() -> Result<()> { test_client.submit_blocking(Grant::account_permission(permission, bob_id.clone()))?; // register asset definitions by "bob@kingdom" so he is owner of it - let coin = AssetDefinition::numeric(coin_id.clone()); + let coin = AssetDefinition::new(coin_id.clone()); let transaction = TransactionBuilder::new(network.chain_id(), bob_id.clone()) .with_instructions([Register::asset_definition(coin)]) .sign(bob_keypair.private_key()); @@ -204,7 +204,6 @@ fn domain_owner_asset_permissions() -> Result<()> { let kingdom_id: DomainId = "kingdom".parse()?; let (bob_id, bob_keypair) = gen_account_in("kingdom"); let coin_id: AssetDefinitionId = "coin#kingdom".parse()?; - let store_id: AssetDefinitionId = "store#kingdom".parse()?; // "alice@wonderland" is owner of "kingdom" domain let kingdom = Domain::new(kingdom_id.clone()); @@ -218,38 +217,23 @@ fn domain_owner_asset_permissions() -> Result<()> { test_client.submit_blocking(Grant::account_permission(permission, bob_id.clone()))?; // register asset definitions by "bob@kingdom" so he is owner of it - let coin = AssetDefinition::numeric(coin_id.clone()); - let store = AssetDefinition::store(store_id.clone()); + let coin = AssetDefinition::new(coin_id.clone()); let transaction = TransactionBuilder::new(network.chain_id(), bob_id.clone()) - .with_instructions([ - Register::asset_definition(coin), - Register::asset_definition(store), - ]) + .with_instructions([Register::asset_definition(coin)]) .sign(bob_keypair.private_key()); test_client.submit_transaction_blocking(&transaction)?; - // check that "alice@wonderland" as owner of domain can register and unregister assets in her domain - let bob_coin_id = AssetId::new(coin_id, bob_id.clone()); - let bob_coin = Asset::new(bob_coin_id.clone(), 30_u32); - test_client.submit_blocking(Register::asset(bob_coin))?; - test_client.submit_blocking(Unregister::asset(bob_coin_id.clone()))?; - // check that "alice@wonderland" as owner of domain can burn, mint and transfer assets in her domain - test_client.submit_blocking(Mint::asset_numeric(10u32, bob_coin_id.clone()))?; - test_client.submit_blocking(Burn::asset_numeric(5u32, bob_coin_id.clone()))?; - test_client.submit_blocking(Transfer::asset_numeric(bob_coin_id, 5u32, alice_id))?; + let bob_coin = AssetId::new(coin_id, bob_id.clone()); + test_client.submit_blocking(Mint::asset_numeric(10u32, bob_coin.clone()))?; + test_client.submit_blocking(Burn::asset_numeric(5u32, bob_coin.clone()))?; + test_client.submit_blocking(Transfer::asset_numeric(bob_coin.clone(), 5u32, alice_id))?; - // check that "alice@wonderland" as owner of domain can edit metadata of store asset in her domain - let key: Name = "key".parse()?; - let value = Json::new("value"); - let bob_store_id = AssetId::new(store_id, bob_id.clone()); - test_client.submit_blocking(SetKeyValue::asset(bob_store_id.clone(), key.clone(), value))?; - test_client.submit_blocking(RemoveKeyValue::asset(bob_store_id.clone(), key))?; + // TODO: test non-fungible assets - // check that "alice@wonderland" as owner of domain can grant and revoke asset related permissions in her domain - let permission = CanUnregisterAsset { - asset: bob_store_id, - }; + // check that "alice@wonderland" as owner of domain + // can grant and revoke asset related permissions in her domain + let permission = CanMintAsset { asset: bob_coin }; test_client.submit_blocking(Grant::account_permission( permission.clone(), bob_id.clone(), diff --git a/crates/iroha/tests/integration/triggers/by_call_trigger.rs b/crates/iroha/tests/integration/triggers/by_call_trigger.rs index edd2e954f7d..85a12277245 100644 --- a/crates/iroha/tests/integration/triggers/by_call_trigger.rs +++ b/crates/iroha/tests/integration/triggers/by_call_trigger.rs @@ -3,7 +3,7 @@ use std::{sync::mpsc, thread, time::Duration}; use executor_custom_data_model::mint_rose_args::MintRoseArgs; use eyre::{eyre, Result, WrapErr}; use iroha::{ - client::{self}, + client::{self, Client}, crypto::KeyPair, data_model::{ prelude::*, @@ -15,8 +15,6 @@ use iroha_executor_data_model::permission::trigger::CanRegisterTrigger; use iroha_test_network::*; use iroha_test_samples::{load_sample_wasm, ALICE_ID}; -use crate::integration::triggers::get_asset_value; - const TRIGGER_NAME: &str = "mint_rose"; #[test] @@ -589,6 +587,15 @@ fn unregistering_one_of_two_triggers_with_identical_wasm_should_not_cause_origin Ok(()) } +fn get_asset_value(client: &Client, asset_id: AssetId) -> Numeric { + let asset = client + .query(client::asset::all()) + .filter_with(|asset| asset.id.eq(asset_id)) + .execute_single() + .unwrap(); + *asset.value() +} + fn build_register_trigger_isi( account_id: &AccountId, trigger_instructions: Vec, diff --git a/crates/iroha/tests/integration/triggers/data_trigger.rs b/crates/iroha/tests/integration/triggers/data_trigger.rs index b882356b21c..06d73162967 100644 --- a/crates/iroha/tests/integration/triggers/data_trigger.rs +++ b/crates/iroha/tests/integration/triggers/data_trigger.rs @@ -13,16 +13,12 @@ fn must_execute_both_triggers() -> Result<()> { let asset_id = AssetId::new(asset_definition_id, account_id.clone()); let get_asset_value = |iroha: &client::Client, asset_id: AssetId| -> Numeric { - match *iroha + *iroha .query(client::asset::all()) .filter_with(|asset| asset.id.eq(asset_id)) .execute_single() .unwrap() .value() - { - AssetValue::Numeric(val) => val, - _ => panic!("Expected u32 asset value"), - } }; let prev_value = get_asset_value(&test_client, asset_id.clone()); diff --git a/crates/iroha/tests/integration/triggers/event_trigger.rs b/crates/iroha/tests/integration/triggers/event_trigger.rs index 001e18acb78..dbc1151b0df 100644 --- a/crates/iroha/tests/integration/triggers/event_trigger.rs +++ b/crates/iroha/tests/integration/triggers/event_trigger.rs @@ -1,10 +1,8 @@ use eyre::Result; -use iroha::data_model::prelude::*; +use iroha::{client, client::Client, data_model::prelude::*}; use iroha_test_network::*; use iroha_test_samples::ALICE_ID; -use crate::integration::triggers::get_asset_value; - #[test] fn test_mint_asset_when_new_asset_definition_created() -> Result<()> { let (network, _rt) = NetworkBuilder::new().start_blocking()?; @@ -29,7 +27,7 @@ fn test_mint_asset_when_new_asset_definition_created() -> Result<()> { let tea_definition_id = "tea#wonderland".parse()?; let register_tea_definition = - Register::asset_definition(AssetDefinition::numeric(tea_definition_id)); + Register::asset_definition(AssetDefinition::new(tea_definition_id)); test_client.submit_blocking(register_tea_definition)?; let new_value = get_asset_value(&test_client, asset_id); @@ -37,3 +35,12 @@ fn test_mint_asset_when_new_asset_definition_created() -> Result<()> { Ok(()) } + +fn get_asset_value(client: &Client, asset_id: AssetId) -> Numeric { + let asset = client + .query(client::asset::all()) + .filter_with(|asset| asset.id.eq(asset_id)) + .execute_single() + .unwrap(); + *asset.value() +} diff --git a/crates/iroha/tests/integration/triggers/mod.rs b/crates/iroha/tests/integration/triggers/mod.rs index 74c374352cc..066b5ea63d0 100644 --- a/crates/iroha/tests/integration/triggers/mod.rs +++ b/crates/iroha/tests/integration/triggers/mod.rs @@ -1,10 +1,3 @@ -use assert_matches::assert_matches; -use iroha::{client, client::Client}; -use iroha_data_model::{ - asset::{AssetId, AssetValue}, - prelude::{Numeric, QueryBuilderExt}, -}; - mod by_call_trigger; mod data_trigger; mod event_trigger; @@ -12,13 +5,3 @@ mod orphans; // FIXME: rewrite all in async and with shorter timings mod time_trigger; mod trigger_rollback; - -fn get_asset_value(client: &Client, asset_id: AssetId) -> Numeric { - let asset = client - .query(client::asset::all()) - .filter_with(|asset| asset.id.eq(asset_id)) - .execute_single() - .unwrap(); - - assert_matches!(*asset.value(), AssetValue::Numeric(val) => val) -} diff --git a/crates/iroha/tests/integration/triggers/time_trigger.rs b/crates/iroha/tests/integration/triggers/time_trigger.rs index be1e9fc49cc..74b28254213 100644 --- a/crates/iroha/tests/integration/triggers/time_trigger.rs +++ b/crates/iroha/tests/integration/triggers/time_trigger.rs @@ -11,9 +11,7 @@ use iroha::{ }, }; use iroha_test_network::*; -use iroha_test_samples::{gen_account_in, load_sample_wasm, ALICE_ID}; - -use crate::integration::triggers::get_asset_value; +use iroha_test_samples::ALICE_ID; fn curr_time() -> Duration { use std::time::SystemTime; @@ -25,6 +23,7 @@ fn curr_time() -> Duration { #[test] fn mint_asset_after_3_sec() -> Result<()> { + const GAP: Duration = Duration::from_secs(3); let (network, _rt) = NetworkBuilder::new() .with_default_pipeline_time() .start_blocking()?; @@ -43,7 +42,6 @@ fn mint_asset_after_3_sec() -> Result<()> { })?; let start_time = curr_time(); - const GAP: Duration = Duration::from_secs(3); assert!( GAP < network.pipeline_time(), "Schedule should be in the future but within block estimation" @@ -129,93 +127,6 @@ fn pre_commit_trigger_should_be_executed() -> Result<()> { Ok(()) } -#[test] -fn mint_nft_for_every_user_every_1_sec() -> Result<()> { - const TRIGGER_PERIOD: Duration = Duration::from_millis(1000); - const EXPECTED_COUNT: u64 = 4; - - let (network, _rt) = NetworkBuilder::new() - .with_default_pipeline_time() - .start_blocking()?; - let test_client = network.client(); - - let alice_id = ALICE_ID.clone(); - - let accounts: Vec = vec![ - alice_id.clone(), - gen_account_in("wonderland").0, - gen_account_in("wonderland").0, - gen_account_in("wonderland").0, - gen_account_in("wonderland").0, - ]; - - // Registering accounts - let register_accounts = accounts - .iter() - .skip(1) // Alice has already been registered in genesis - .cloned() - .map(|account_id| Register::account(Account::new(account_id))) - .collect::>(); - test_client.submit_all_blocking(register_accounts)?; - - // Start listening BEFORE submitting any transaction not to miss any block committed event - let event_listener = get_block_committed_event_listener(&test_client)?; - - // Registering trigger - // Offset into the future to be able to register trigger - let offset = Duration::from_secs(10); - let start_time = curr_time() + offset; - let schedule = TimeSchedule::starting_at(start_time).with_period(TRIGGER_PERIOD); - - let filter = TimeEventFilter(ExecutionTime::Schedule(schedule)); - let register_trigger = Register::trigger(Trigger::new( - "mint_nft_for_all".parse()?, - Action::new( - load_sample_wasm("create_nft_for_every_user_trigger"), - Repeats::Indefinitely, - alice_id.clone(), - filter, - ), - )); - test_client.submit_blocking(register_trigger)?; - std::thread::sleep(offset); - - // Time trigger will be executed on block commits, so we have to produce some transactions - submit_sample_isi_on_every_block_commit( - event_listener, - &test_client, - &alice_id, - TRIGGER_PERIOD, - usize::try_from(EXPECTED_COUNT)?, - )?; - - // Checking results - for account_id in accounts { - let start_pattern = "nft_number_"; - let end_pattern = format!("_for_{}#{}", account_id.signatory(), account_id.domain()); - let assets = test_client - .query(client::asset::all()) - .filter_with(|asset| asset.id.account.eq(account_id.clone())) - .execute_all()?; - let count: u64 = assets - .into_iter() - .filter(|asset| { - let s = asset.id().definition().to_string(); - s.starts_with(start_pattern) && s.ends_with(&end_pattern) - }) - .count() - .try_into() - .expect("`usize` should always fit in `u64`"); - - assert!( - count >= EXPECTED_COUNT, - "{account_id} has {count} NFTs, but at least {EXPECTED_COUNT} expected", - ); - } - - Ok(()) -} - /// Get block committed event listener fn get_block_committed_event_listener( client: &Client, @@ -224,24 +135,12 @@ fn get_block_committed_event_listener( client.listen_for_events([block_filter]) } -/// Submit some sample ISIs to create new blocks -fn submit_sample_isi_on_every_block_commit( - block_committed_event_listener: impl Iterator>, - test_client: &Client, - account_id: &AccountId, - timeout: Duration, - times: usize, -) -> Result<()> { - for _ in block_committed_event_listener.take(times) { - std::thread::sleep(timeout); - // ISI just to create a new block - let sample_isi = SetKeyValue::account( - account_id.clone(), - "key".parse::()?, - Json::new("value"), - ); - test_client.submit(sample_isi)?; - } - - Ok(()) +/// Get asset numeric value +fn get_asset_value(client: &Client, asset_id: AssetId) -> Numeric { + let asset = client + .query(client::asset::all()) + .filter_with(|asset| asset.id.eq(asset_id)) + .execute_single() + .unwrap(); + *asset.value() } diff --git a/crates/iroha/tests/integration/triggers/trigger_rollback.rs b/crates/iroha/tests/integration/triggers/trigger_rollback.rs index 9d807c326e3..1aeca2cf731 100644 --- a/crates/iroha/tests/integration/triggers/trigger_rollback.rs +++ b/crates/iroha/tests/integration/triggers/trigger_rollback.rs @@ -16,7 +16,7 @@ fn failed_trigger_revert() -> Result<()> { let account_id = ALICE_ID.clone(); let asset_definition_id = "xor#wonderland".parse::()?; let create_asset = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); + Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())); let fail_isi = Unregister::domain("dummy".parse().unwrap()); let instructions: [InstructionBox; 2] = [create_asset.into(), fail_isi.into()]; let register_trigger = Register::trigger(Trigger::new( diff --git a/crates/iroha/tests/integration/tx_chain_id.rs b/crates/iroha/tests/integration/tx_chain_id.rs index c885ed2bec6..2551fa49c35 100644 --- a/crates/iroha/tests/integration/tx_chain_id.rs +++ b/crates/iroha/tests/integration/tx_chain_id.rs @@ -18,17 +18,17 @@ fn send_tx_with_different_chain_id() { let create_sender_account = Register::account(Account::new(sender_id.clone())); let create_receiver_account = Register::account(Account::new(receiver_id.clone())); let register_asset_definition = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); - let register_asset = Register::asset(Asset::new( - AssetId::new(asset_definition_id.clone(), sender_id.clone()), + Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())); + let mint_asset = Mint::asset_numeric( numeric!(10), - )); + AssetId::new(asset_definition_id.clone(), sender_id.clone()), + ); test_client .submit_all_blocking::([ create_sender_account.into(), create_receiver_account.into(), register_asset_definition.into(), - register_asset.into(), + mint_asset.into(), ]) .unwrap(); let chain_id_0 = network.chain_id(); diff --git a/crates/iroha/tests/integration/tx_history.rs b/crates/iroha/tests/integration/tx_history.rs index adcafebcf4d..ea70a6f17bb 100644 --- a/crates/iroha/tests/integration/tx_history.rs +++ b/crates/iroha/tests/integration/tx_history.rs @@ -16,7 +16,7 @@ fn client_has_rejected_and_accepted_txs_should_return_tx_history() -> Result<()> let account_id = ALICE_ID.clone(); let asset_definition_id = "xor#wonderland".parse::()?; let create_asset = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); + Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())); client.submit_blocking(create_asset)?; //When diff --git a/crates/iroha/tests/integration/tx_rollback.rs b/crates/iroha/tests/integration/tx_rollback.rs index 4c11cf5531e..9dd4e6ad699 100644 --- a/crates/iroha/tests/integration/tx_rollback.rs +++ b/crates/iroha/tests/integration/tx_rollback.rs @@ -12,7 +12,7 @@ fn client_sends_transaction_with_invalid_instruction_should_not_see_any_changes( let account_id = ALICE_ID.clone(); let asset_definition_id = "xor#wonderland".parse()?; let wrong_asset_definition_id = "ksor#wonderland".parse::()?; - let create_asset = Register::asset_definition(AssetDefinition::numeric(asset_definition_id)); + let create_asset = Register::asset_definition(AssetDefinition::new(asset_definition_id)); let mint_asset = Mint::asset_numeric( 200u32, AssetId::new(wrong_asset_definition_id.clone(), account_id.clone()), diff --git a/crates/iroha/tests/integration/upgrade.rs b/crates/iroha/tests/integration/upgrade.rs index cadffa048e4..4356d554c81 100644 --- a/crates/iroha/tests/integration/upgrade.rs +++ b/crates/iroha/tests/integration/upgrade.rs @@ -3,10 +3,7 @@ use eyre::Result; use futures_util::TryStreamExt as _; use iroha::{ client::{self, Client}, - data_model::{ - parameter::{Parameter, SmartContractParameter}, - prelude::*, - }, + data_model::{parameter::SmartContractParameter, prelude::*}, }; use iroha_executor_data_model::permission::{domain::CanUnregisterDomain, Permission as _}; use iroha_test_network::*; @@ -247,16 +244,15 @@ fn executor_custom_instructions_complex() -> Result<()> { let (network, _rt) = NetworkBuilder::new().start_blocking()?; let client = network.client(); - let executor_fuel_limit = SetParameter::new(Parameter::Executor(SmartContractParameter::Fuel( - nonzero!(1_000_000_000_u64), - ))); - client.submit_blocking(executor_fuel_limit)?; + let executor_fuel_limit = + Parameter::Executor(SmartContractParameter::Fuel(nonzero!(1_000_000_000_u64))); + client.submit_blocking(SetParameter(executor_fuel_limit))?; upgrade_executor(&client, "executor_custom_instructions_complex")?; // Give 6 roses to bob let asset_definition_id: AssetDefinitionId = "rose#wonderland".parse().unwrap(); let bob_rose = AssetId::new(asset_definition_id.clone(), BOB_ID.clone()); - client.submit_blocking(Mint::asset_numeric(Numeric::from(6u32), bob_rose.clone()))?; + client.submit_blocking(Mint::asset_numeric(numeric!(6), bob_rose.clone()))?; // Check that bob has 6 roses assert_eq!( @@ -264,7 +260,7 @@ fn executor_custom_instructions_complex() -> Result<()> { Numeric::from(6u32) ); - // If bob has more then 5 roses, then burn 1 rose + // If bob has more than 5 roses, then burn 1 rose let burn_bob_rose_if_more_then_5 = || -> Result<()> { let condition = Greater::new( EvaluatesTo::new_unchecked(Expression::Query( @@ -382,9 +378,8 @@ fn define_custom_parameter() -> Result<()> { let parameter = DomainLimits { id_len: 2_u32.pow(6), - } - .into(); - let set_param_isi = SetParameter::new(parameter); + }; + let set_param_isi = SetParameter(parameter.into()); client.submit_all_blocking::([set_param_isi.into(), create_domain.into()])?; Ok(()) diff --git a/crates/iroha_cli/src/main.rs b/crates/iroha_cli/src/main.rs index 6afb8ee7033..acc8e1380b3 100644 --- a/crates/iroha_cli/src/main.rs +++ b/crates/iroha_cli/src/main.rs @@ -686,10 +686,7 @@ mod account { } mod asset { - use iroha::{ - client::{self, asset}, - data_model::name::Name, - }; + use iroha::client::{self, asset}; use super::*; @@ -710,25 +707,19 @@ mod asset { /// List assets #[clap(subcommand)] List(List), - /// Get a value from a Store asset - GetKeyValue(GetKeyValue), - /// Set a key-value entry in a Store asset - SetKeyValue(SetKeyValue), - /// Remove a key-value entry from a Store asset - RemoveKeyValue(RemoveKeyValue), } impl RunArgs for Args { fn run(self, context: &mut dyn RunContext) -> Result<()> { match_all!( (self, context), - { Args::Definition, Args::Mint, Args::Burn, Args::Transfer, Args::Get, Args::List, Args::SetKeyValue, Args::RemoveKeyValue, Args::GetKeyValue} + { Args::Definition, Args::Mint, Args::Burn, Args::Transfer, Args::Get, Args::List} ) } } mod definition { - use iroha::data_model::asset::{AssetDefinition, AssetDefinitionId, AssetType}; + use iroha::data_model::asset::{AssetDefinition, AssetDefinitionId}; use super::*; @@ -762,7 +753,7 @@ mod asset { pub unmintable: bool, /// Value type stored in asset #[arg(short, long)] - pub r#type: AssetType, + pub spec: NumericSpec, #[command(flatten)] pub metadata: MetadataArgs, } @@ -771,11 +762,11 @@ mod asset { fn run(self, context: &mut dyn RunContext) -> Result<()> { let Self { id: asset_id, - r#type, + spec, unmintable, metadata, } = self; - let mut asset_definition = AssetDefinition::new(asset_id, r#type); + let mut asset_definition = AssetDefinition::new(asset_id).with_numeric_spec(spec); if unmintable { asset_definition = asset_definition.mintable_once(); } @@ -946,73 +937,6 @@ mod asset { Ok(()) } } - - #[derive(clap::Args, Debug)] - pub struct SetKeyValue { - /// Asset id for the Store asset (in form of `asset##account@domain_name`) - #[clap(long)] - pub id: AssetId, - /// The key for the store value - #[clap(long)] - pub key: Name, - #[command(flatten)] - pub value: MetadataValueArg, - } - - impl RunArgs for SetKeyValue { - fn run(self, context: &mut dyn RunContext) -> Result<()> { - let Self { - id: asset_id, - key, - value: MetadataValueArg { value }, - } = self; - - let set = iroha::data_model::isi::SetKeyValue::asset(asset_id, key, value); - submit([set], Metadata::default(), context)?; - Ok(()) - } - } - #[derive(clap::Args, Debug)] - pub struct RemoveKeyValue { - /// Asset id for the Store asset (in form of `asset##account@domain_name`) - #[clap(long)] - pub id: AssetId, - /// The key for the store value - #[clap(long)] - pub key: Name, - } - - impl RunArgs for RemoveKeyValue { - fn run(self, context: &mut dyn RunContext) -> Result<()> { - let Self { id: asset_id, key } = self; - let remove = iroha::data_model::isi::RemoveKeyValue::asset(asset_id, key); - submit([remove], Metadata::default(), context)?; - Ok(()) - } - } - - #[derive(clap::Args, Debug)] - pub struct GetKeyValue { - /// Asset id for the Store asset (in form of `asset##account@domain_name`) - #[clap(long)] - pub id: AssetId, - /// The key for the store value - #[clap(long)] - pub key: Name, - } - - impl RunArgs for GetKeyValue { - fn run(self, context: &mut dyn RunContext) -> Result<()> { - let Self { id: asset_id, key } = self; - let client = context.client_from_config(); - let find_key_value = FindAssetMetadata::new(asset_id, key); - let asset = client - .query_single(find_key_value) - .wrap_err("Failed to get key-value")?; - context.print_data(&asset)?; - Ok(()) - } - } } mod peer { diff --git a/crates/iroha_core/benches/blocks/common.rs b/crates/iroha_core/benches/blocks/common.rs index fa9aafa6fca..9b0435779c4 100644 --- a/crates/iroha_core/benches/blocks/common.rs +++ b/crates/iroha_core/benches/blocks/common.rs @@ -98,7 +98,7 @@ pub fn populate_state( } for asset_definition_id in asset_definitions { - let asset_definition = AssetDefinition::numeric(asset_definition_id.clone()); + let asset_definition = AssetDefinition::new(asset_definition_id.clone()); instructions.push(Register::asset_definition(asset_definition).into()); let can_unregister_asset_definition = Grant::account_permission( CanUnregisterAssetDefinition { @@ -175,7 +175,7 @@ pub fn restore_every_nth( .enumerate() { if k % nth == 0 || i % nth == 0 { - let asset_definition = AssetDefinition::numeric(asset_definition_id.clone()); + let asset_definition = AssetDefinition::new(asset_definition_id.clone()); instructions.push(Register::asset_definition(asset_definition).into()); } } diff --git a/crates/iroha_core/benches/validation.rs b/crates/iroha_core/benches/validation.rs index 6c25ba3ef7e..7c0126b477f 100644 --- a/crates/iroha_core/benches/validation.rs +++ b/crates/iroha_core/benches/validation.rs @@ -24,7 +24,7 @@ fn build_test_transaction(chain_id: ChainId) -> TransactionBuilder { let create_domain = Register::domain(Domain::new(domain_id.clone())); let create_account = Register::account(Account::new(gen_account_in(&domain_id).0)); let asset_definition_id = "xor#domain".parse().unwrap(); - let create_asset = Register::asset_definition(AssetDefinition::numeric(asset_definition_id)); + let create_asset = Register::asset_definition(AssetDefinition::new(asset_definition_id)); TransactionBuilder::new(chain_id, STARTER_ID.clone()).with_instructions::([ create_domain.into(), diff --git a/crates/iroha_core/src/block.rs b/crates/iroha_core/src/block.rs index e2f473b8d51..52a40d74670 100644 --- a/crates/iroha_core/src/block.rs +++ b/crates/iroha_core/src/block.rs @@ -1177,7 +1177,7 @@ mod tests { // Creating an instruction let asset_definition_id = "xor#wonderland".parse().expect("Valid"); let create_asset_definition = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id)); + Register::asset_definition(AssetDefinition::new(asset_definition_id)); // Making two transactions that have the same instruction let tx = TransactionBuilder::new(chain_id.clone(), alice_id) @@ -1239,7 +1239,7 @@ mod tests { .parse::() .expect("Valid"); let create_asset_definition = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); + Register::asset_definition(AssetDefinition::new(asset_definition_id.clone())); // Making two transactions that have the same instruction let tx = TransactionBuilder::new(chain_id.clone(), alice_id.clone()) @@ -1319,8 +1319,7 @@ mod tests { let domain_id = "domain".parse().expect("Valid"); let create_domain = Register::domain(Domain::new(domain_id)); let asset_definition_id = "coin#domain".parse().expect("Valid"); - let create_asset = - Register::asset_definition(AssetDefinition::numeric(asset_definition_id)); + let create_asset = Register::asset_definition(AssetDefinition::new(asset_definition_id)); let fail_isi = Unregister::domain("dummy".parse().unwrap()); let tx_fail = TransactionBuilder::new(chain_id.clone(), alice_id.clone()) .with_instructions::([create_domain.clone().into(), fail_isi.into()]) diff --git a/crates/iroha_core/src/smartcontracts/isi/account.rs b/crates/iroha_core/src/smartcontracts/isi/account.rs index 914b1311b12..2a28359c4a6 100644 --- a/crates/iroha_core/src/smartcontracts/isi/account.rs +++ b/crates/iroha_core/src/smartcontracts/isi/account.rs @@ -24,144 +24,11 @@ impl Registrable for iroha_data_model::account::NewAccount { /// - grant permissions and roles /// - Revoke permissions or roles pub mod isi { - use iroha_data_model::{ - asset::{AssetType, AssetValue}, - isi::{ - error::{MintabilityError, RepetitionError}, - InstructionType, - }, - query::error::QueryExecutionFail, - }; - use iroha_primitives::numeric::Numeric; + use iroha_data_model::isi::{error::RepetitionError, InstructionType}; - use self::asset::isi::assert_numeric_spec; use super::*; use crate::{role::RoleIdWithOwner, state::StateTransaction}; - impl Execute for Register { - #[metrics(+"register_asset")] - fn execute( - self, - _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, - ) -> Result<(), Error> { - let asset_id = self.object.id; - - match state_transaction.world.asset(&asset_id) { - Err(err) => match err { - QueryExecutionFail::Find(FindError::Asset(_)) => { - assert_can_register( - &asset_id.definition, - state_transaction, - &self.object.value, - )?; - let asset = state_transaction - .world - .asset_or_insert(asset_id.clone(), self.object.value) - .expect("Account exists"); - - match asset.value { - AssetValue::Numeric(increment) => { - state_transaction - .world - .increase_asset_total_amount(&asset_id.definition, increment)?; - } - AssetValue::Store(_) => { - state_transaction.world.increase_asset_total_amount( - &asset_id.definition, - Numeric::ONE, - )?; - } - } - Ok(()) - } - _ => Err(err.into()), - }, - Ok(_) => Err(RepetitionError { - instruction: InstructionType::Register, - id: IdBox::AssetId(asset_id.clone()), - } - .into()), - } - } - } - - impl Execute for Unregister { - #[metrics(+"unregister_asset")] - fn execute( - self, - _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, - ) -> Result<(), Error> { - let asset_id = self.object; - - let asset = state_transaction - .world - .assets - .remove(asset_id.clone()) - .ok_or_else(|| FindError::Asset(asset_id))?; - - match asset.value { - AssetValue::Numeric(increment) => { - state_transaction - .world - .decrease_asset_total_amount(&asset.id.definition, increment)?; - } - AssetValue::Store(_) => { - state_transaction - .world - .decrease_asset_total_amount(&asset.id.definition, Numeric::ONE)?; - } - } - - state_transaction - .world - .emit_events(Some(AccountEvent::Asset(AssetEvent::Removed( - AssetChanged { - asset: asset.id, - amount: asset.value, - }, - )))); - - Ok(()) - } - } - - impl Execute for Transfer { - fn execute( - self, - _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, - ) -> Result<(), Error> { - let Transfer { - source, - object, - destination, - } = self; - - let _ = state_transaction.world.account(&source)?; - let _ = state_transaction.world.account(&destination)?; - - let asset_definition = state_transaction.world.asset_definition_mut(&object)?; - - if asset_definition.owned_by != source { - return Err(Error::Find(FindError::Account(source))); - } - - asset_definition.owned_by = destination.clone(); - state_transaction - .world - .emit_events(Some(AssetDefinitionEvent::OwnerChanged( - AssetDefinitionOwnerChanged { - asset_definition: object, - new_owner: destination, - }, - ))); - - Ok(()) - } - } - impl Execute for SetKeyValue { #[metrics(+"set_account_key_value")] fn execute( @@ -369,70 +236,6 @@ pub mod isi { Ok(()) } } - - /// Assert that this asset can be registered to an account. - fn assert_can_register( - definition_id: &AssetDefinitionId, - state_transaction: &mut StateTransaction<'_, '_>, - value: &AssetValue, - ) -> Result<(), Error> { - let expected_asset_type = match value.type_() { - AssetType::Numeric(_) => asset::isi::expected_asset_type_numeric, - AssetType::Store => asset::isi::expected_asset_type_store, - }; - let definition = - asset::isi::assert_asset_type(definition_id, state_transaction, expected_asset_type)?; - if let AssetValue::Numeric(numeric) = value { - assert_numeric_spec(numeric, &definition)?; - } - - match definition.mintable { - Mintable::Infinitely => Ok(()), - Mintable::Not => Err(Error::Mintability(MintabilityError::MintUnmintable)), - Mintable::Once => { - if !value.is_zero_value() { - let asset_definition = state_transaction - .world - .asset_definition_mut(definition_id)?; - forbid_minting(asset_definition)?; - state_transaction.world.emit_events(Some( - AssetDefinitionEvent::MintabilityChanged(definition_id.clone()), - )); - } - Ok(()) - } - } - } - - /// Stop minting on the [`AssetDefinition`] globally. - /// - /// # Errors - /// If the [`AssetDefinition`] is not `Mintable::Once`. - #[inline] - pub fn forbid_minting(definition: &mut AssetDefinition) -> Result<(), MintabilityError> { - if definition.mintable == Mintable::Once { - definition.mintable = Mintable::Not; - Ok(()) - } else { - Err(MintabilityError::ForbidMintOnMintable) - } - } - - #[cfg(test)] - mod test { - use iroha_data_model::{prelude::AssetDefinition, ParseError}; - use iroha_test_samples::gen_account_in; - - use crate::smartcontracts::isi::Registrable as _; - - #[test] - fn cannot_forbid_minting_on_asset_mintable_infinitely() -> Result<(), ParseError> { - let (authority, _authority_keypair) = gen_account_in("wonderland"); - let mut definition = AssetDefinition::numeric("test#hello".parse()?).build(&authority); - assert!(super::forbid_minting(&mut definition).is_err()); - Ok(()) - } - } } /// Account-related [`Query`] instructions. diff --git a/crates/iroha_core/src/smartcontracts/isi/asset.rs b/crates/iroha_core/src/smartcontracts/isi/asset.rs index 9db957022ca..4ced881a21c 100644 --- a/crates/iroha_core/src/smartcontracts/isi/asset.rs +++ b/crates/iroha_core/src/smartcontracts/isi/asset.rs @@ -1,10 +1,9 @@ -//! This module contains [`Asset`] structure, it's implementation and related traits and -//! instructions implementations. +//! ## Asset ISI and queries use iroha_data_model::{ isi::error::{MathError, Mismatch, TypeError}, prelude::*, - query::error::{FindError, QueryExecutionFail}, + query::error::FindError, }; use iroha_telemetry::metrics; @@ -18,7 +17,7 @@ impl Registrable for NewAssetDefinition { fn build(self, authority: &AccountId) -> Self::Target { Self::Target { id: self.id, - type_: self.type_, + spec: self.spec, mintable: self.mintable, logo: self.logo, metadata: self.metadata, @@ -33,135 +32,168 @@ impl Registrable for NewAssetDefinition { /// - update metadata /// - transfer, etc. pub mod isi { - use iroha_data_model::{asset::AssetType, isi::error::MintabilityError}; + use iroha_data_model::isi::error::{MintabilityError, RepetitionError}; use super::*; - use crate::smartcontracts::account::isi::forbid_minting; - impl Execute for SetKeyValue { - #[metrics(+"set_asset_key_value")] + impl Execute for Register { + #[metrics(+"register_asset_definition")] fn execute( self, - _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, + authority: &AccountId, + state_transaction: &mut StateTransaction, ) -> Result<(), Error> { - let asset_id = self.object; - - assert_asset_type( - &asset_id.definition, - state_transaction, - expected_asset_type_store, - )?; - - // Increase `Store` asset total quantity by 1 if asset was not present earlier - if matches!( - state_transaction.world.asset(&asset_id), - Err(QueryExecutionFail::Find(_)) - ) { - state_transaction - .world - .increase_asset_total_amount(&asset_id.definition, Numeric::ONE)?; - } - - let asset = state_transaction - .world - .asset_or_insert(asset_id.clone(), Metadata::default())?; + let asset_definition = self.object.build(authority); - { - let AssetValue::Store(store) = &mut asset.value else { - return Err(Error::Conversion("Expected store asset type".to_owned())); - }; - - store.insert(self.key.clone(), self.value.clone()); + let world = &mut state_transaction.world; + if world.asset_definition(&asset_definition.id).is_ok() { + return Err(RepetitionError { + instruction: InstructionType::Register, + id: IdBox::AssetDefinitionId(asset_definition.id), + } + .into()); } + world.domain(&asset_definition.id.domain)?; - state_transaction - .world - .emit_events(Some(AssetEvent::MetadataInserted(MetadataChanged { - target: asset_id, - key: self.key, - value: self.value, - }))); + world + .asset_definitions + .insert(asset_definition.id.clone(), asset_definition.clone()); + world.emit_events(Some(AssetDefinitionEvent::Created(asset_definition))); Ok(()) } } - impl Execute for RemoveKeyValue { - #[metrics(+"remove_asset_key_value")] + impl Execute for Unregister { + #[metrics(+"unregister_asset_definition")] fn execute( self, _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, + state_transaction: &mut StateTransaction, ) -> Result<(), Error> { - let asset_id = self.object; + let asset_definition = self.object; + let world = &mut state_transaction.world; + + world.asset_definition(&asset_definition)?; + + let assets_to_remove = world + .assets + .iter() + .filter(|(asset, _)| asset.definition == asset_definition) + .map(|(asset, _)| asset) + .cloned() + .collect::>(); + + let mut events = Vec::with_capacity(assets_to_remove.len() + 1); + for asset in assets_to_remove { + let removed = world + .assets + .remove(asset) + .expect("INTERNAL BUG: asset should be removed"); + events.push(AssetEvent::Deleted(removed.id).into()); + } + + world + .asset_definitions + .remove(asset_definition.clone()) + .expect("INTERNAL BUG: asset definition should be removed"); + world + .domain(&asset_definition.domain) + .expect("INTERNAL BUG: domain should exist"); - assert_asset_type( - &asset_id.definition, - state_transaction, - expected_asset_type_store, - )?; + events.push(AssetDefinitionEvent::Deleted(asset_definition).into()); - let value = { - let asset = state_transaction.world.asset_mut(&asset_id)?; + world.emit_events::<_, DataEvent>(events); + Ok(()) + } + } - let AssetValue::Store(store) = &mut asset.value else { - return Err(Error::Conversion("Expected store asset type".to_owned())); - }; + impl Execute for SetKeyValue { + #[metrics(+"set_key_value_asset_definition")] + fn execute( + self, + _authority: &AccountId, + state_transaction: &mut StateTransaction, + ) -> Result<(), Error> { + let asset_definition_id = self.object; + let world = &mut state_transaction.world; + world + .asset_definition_mut(&asset_definition_id)? + .metadata + .insert(self.key.clone(), self.value.clone()); + world.emit_events(Some(AssetDefinitionEvent::MetadataInserted( + MetadataChanged { + target: asset_definition_id, + key: self.key, + value: self.value, + }, + ))); + Ok(()) + } + } - store - .remove(&self.key) - .ok_or_else(|| FindError::MetadataKey(self.key.clone()))? + impl Execute for RemoveKeyValue { + #[metrics(+"remove_key_value_asset_definition")] + fn execute( + self, + _authority: &AccountId, + state_transaction: &mut StateTransaction, + ) -> Result<(), Error> { + let asset_definition_id = self.object; + + let world = &mut state_transaction.world; + let Some(value) = world + .asset_definition_mut(&asset_definition_id)? + .metadata + .remove(&self.key) + else { + return Err(FindError::MetadataKey(self.key).into()); }; state_transaction .world - .emit_events(Some(AssetEvent::MetadataRemoved(MetadataChanged { - target: asset_id, - key: self.key, - value, - }))); + .emit_events(Some(AssetDefinitionEvent::MetadataRemoved( + MetadataChanged { + target: asset_definition_id, + key: self.key, + value, + }, + ))); Ok(()) } } - impl Execute for Transfer { - #[metrics(+"transfer_store")] + impl Execute for Transfer { fn execute( self, _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, + state_transaction: &mut StateTransaction, ) -> Result<(), Error> { - let asset_id = self.source; - assert_asset_type( - &asset_id.definition, - state_transaction, - expected_asset_type_store, - )?; - - let asset = state_transaction - .world - .assets - .get_mut(&asset_id) - .ok_or_else(|| FindError::Asset(asset_id.clone()))?; + let Transfer { + source, + object, + destination, + } = self; - let destination_store = { - let value = asset.value.clone(); + let world = &mut state_transaction.world; - let destination_id = - AssetId::new(asset_id.definition.clone(), self.destination.clone()); - let destination_store_asset = state_transaction - .world - .asset_or_insert(destination_id.clone(), value)?; + let _ = world.account(&source)?; + let _ = world.account(&destination)?; + let asset_definition = world.asset_definition_mut(&object)?; - destination_store_asset.clone() - }; + if asset_definition.owned_by != source { + // FIXME: seems like a bad error for this + return Err(FindError::Account(source).into()); + } + asset_definition.owned_by = destination.clone(); - state_transaction.world.emit_events([ - AssetEvent::Deleted(asset_id), - AssetEvent::Created(destination_store), - ]); + world.emit_events(Some(AssetDefinitionEvent::OwnerChanged( + AssetDefinitionOwnerChanged { + asset_definition: object, + new_owner: destination, + }, + ))); Ok(()) } @@ -171,45 +203,37 @@ pub mod isi { fn execute( self, _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, + state_transaction: &mut StateTransaction, ) -> Result<(), Error> { let asset_id = self.destination; - - let asset_definition = assert_asset_type( - &asset_id.definition, - state_transaction, - expected_asset_type_numeric, - )?; - assert_numeric_spec(&self.object, &asset_definition)?; - - assert_can_mint(&asset_definition, state_transaction)?; - let asset = state_transaction - .world - .asset_or_insert(asset_id.clone(), Numeric::ZERO)?; - let AssetValue::Numeric(quantity) = &mut asset.value else { - return Err(Error::Conversion("Expected numeric asset type".to_owned())); - }; - *quantity = quantity - .checked_add(self.object) - .ok_or(MathError::Overflow)?; - - #[allow(clippy::float_arithmetic)] - { - state_transaction - .new_tx_amounts - .lock() - .push(self.object.to_f64()); - state_transaction - .world - .increase_asset_total_amount(&asset_id.definition, self.object)?; + let amount = self.object; + + let world = &mut state_transaction.world; + + let asset_definition = world.asset_definition_mut(&asset_id.definition)?; + assert_numeric_spec(&amount, &asset_definition)?; + let mintability_changed = assert_can_mint(asset_definition)?; + if mintability_changed { + let asset_definition = asset_definition.id.clone(); + world.emit_events(Some(AssetDefinitionEvent::MintabilityChanged( + asset_definition, + ))) } + let asset = world.asset_or_insert(asset_id.clone())?; + asset.value = asset.value.checked_add(amount).ok_or(MathError::Overflow)?; + + // FIXME: replace with events state_transaction - .world - .emit_events(Some(AssetEvent::Added(AssetChanged { - asset: asset_id, - amount: self.object.into(), - }))); + .new_tx_amounts + .lock() + .push(amount.to_f64()); + world.increase_asset_total_amount(&asset_id.definition, amount)?; + + world.emit_events(Some(AssetEvent::Added(AssetChanged { + asset: asset_id, + amount: amount.into(), + }))); Ok(()) } @@ -219,54 +243,40 @@ pub mod isi { fn execute( self, _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, + state_transaction: &mut StateTransaction, ) -> Result<(), Error> { let asset_id = self.destination; + let amount = self.object; - let asset_definition = assert_asset_type( - &asset_id.definition, - state_transaction, - expected_asset_type_numeric, - )?; - assert_numeric_spec(&self.object, &asset_definition)?; + let world = &mut state_transaction.world; - let asset = state_transaction - .world - .assets - .get_mut(&asset_id) - .ok_or_else(|| FindError::Asset(asset_id.clone()))?; - let AssetValue::Numeric(quantity) = &mut asset.value else { - return Err(Error::Conversion("Expected numeric asset type".to_owned())); + let asset_definition = world.asset_definition(&asset_id.definition)?; + assert_numeric_spec(&amount, &asset_definition)?; + + let Ok(asset) = world.asset_mut(&asset_id) else { + // same as having zero of the asset + return Err(MathError::NotEnoughQuantity.into()); }; - *quantity = quantity - .checked_sub(self.object) + asset.value = asset + .value + .checked_sub(amount) .ok_or(MathError::NotEnoughQuantity)?; - if asset.value.is_zero_value() { - assert!(state_transaction - .world - .assets - .remove(asset_id.clone()) - .is_some()); - } - - #[allow(clippy::float_arithmetic)] - { - state_transaction - .new_tx_amounts - .lock() - .push(self.object.to_f64()); - state_transaction - .world - .decrease_asset_total_amount(&asset_id.definition, self.object)?; + if asset.value.is_zero() { + assert!(world.assets.remove(asset_id.clone()).is_some()); } + // FIXME: replace with events state_transaction - .world - .emit_events(Some(AssetEvent::Removed(AssetChanged { - asset: asset_id.clone(), - amount: self.object.into(), - }))); + .new_tx_amounts + .lock() + .push(amount.to_f64()); + world.decrease_asset_total_amount(&asset_id.definition, amount)?; + + world.emit_events(Some(AssetEvent::Removed(AssetChanged { + asset: asset_id, + amount: amount.into(), + }))); Ok(()) } @@ -276,146 +286,110 @@ pub mod isi { fn execute( self, _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, + state_transaction: &mut StateTransaction, ) -> Result<(), Error> { let source_id = self.source; - let destination_id = - AssetId::new(source_id.definition.clone(), self.destination.clone()); - - let asset_definition = assert_asset_type( - &source_id.definition, - state_transaction, - expected_asset_type_numeric, - )?; - assert_numeric_spec(&self.object, &asset_definition)?; - - { - let asset = state_transaction - .world - .assets - .get_mut(&source_id) - .ok_or_else(|| FindError::Asset(source_id.clone()))?; - let AssetValue::Numeric(quantity) = &mut asset.value else { - return Err(Error::Conversion("Expected numeric asset type".to_owned())); - }; - *quantity = quantity - .checked_sub(self.object) - .ok_or(MathError::NotEnoughQuantity)?; - if asset.value.is_zero_value() { - assert!(state_transaction - .world - .assets - .remove(source_id.clone()) - .is_some()); - } - } + let amount = self.object; - let destination_asset = state_transaction - .world - .asset_or_insert(destination_id.clone(), Numeric::ZERO)?; - { - let AssetValue::Numeric(quantity) = &mut destination_asset.value else { - return Err(Error::Conversion("Expected numeric asset type".to_owned())); - }; - *quantity = quantity - .checked_add(self.object) - .ok_or(MathError::Overflow)?; - } + let world = &mut state_transaction.world; - #[allow(clippy::float_arithmetic)] - { - state_transaction - .new_tx_amounts - .lock() - .push(self.object.to_f64()); + let asset_definition = world.asset_definition(&source_id.definition)?; + assert_numeric_spec(&amount, &asset_definition)?; + + let Ok(source) = world.asset_mut(&source_id) else { + // same as having zero of the asset + return Err(MathError::NotEnoughQuantity.into()); + }; + source.value = source + .value + .checked_sub(amount) + .ok_or(MathError::NotEnoughQuantity)?; + if source.value.is_zero() { + assert!(world.assets.remove(source_id.clone()).is_some()); } - state_transaction.world.emit_events([ + let target_id = AssetId::new(source_id.definition.clone(), self.destination); + let target = world.asset_or_insert(target_id.clone())?; + let value = &mut target.value; + *value = value.checked_add(amount).ok_or(MathError::Overflow)?; + + // FIXME: replace with events + state_transaction + .new_tx_amounts + .lock() + .push(amount.to_f64()); + + world.emit_events([ AssetEvent::Removed(AssetChanged { asset: source_id, - amount: self.object.into(), + amount: amount.into(), }), AssetEvent::Added(AssetChanged { - asset: destination_id, - amount: self.object.into(), + asset: target_id, + amount: amount.into(), }), ]); - Ok(()) } } /// Assert that asset type is Numeric and that it satisfy asset definition spec - pub(crate) fn assert_numeric_spec( + fn assert_numeric_spec( object: &Numeric, asset_definition: &AssetDefinition, ) -> Result { let object_spec = NumericSpec::fractional(object.scale()); - let object_asset_type = AssetType::Numeric(object_spec); - let asset_definition_spec = match asset_definition.type_ { - AssetType::Numeric(spec) => spec, - other => { - return Err(TypeError::from(Mismatch { - expected: other, - actual: object_asset_type, - }) - .into()) - } - }; + let asset_definition_spec = asset_definition.spec; asset_definition_spec.check(object).map_err(|_| { TypeError::from(Mismatch { - expected: AssetType::Numeric(asset_definition_spec), - actual: object_asset_type, + expected: asset_definition_spec, + actual: object_spec, }) })?; Ok(asset_definition_spec) } - /// Asserts that asset definition with [`definition_id`] has asset type [`expected_type`]. - pub(crate) fn assert_asset_type( - definition_id: &AssetDefinitionId, - state_transaction: &StateTransaction<'_, '_>, - expected_type: impl Fn(&AssetType) -> Result<(), TypeError>, - ) -> Result { - let asset_definition = state_transaction.world.asset_definition(definition_id)?; - expected_type(&asset_definition.type_) - .map(|()| asset_definition) - .map_err(Into::into) + /// Stop minting on the [`AssetDefinition`] globally. + /// + /// # Errors + /// If the [`AssetDefinition`] is not `Mintable::Once`. + #[inline] + fn forbid_minting(definition: &mut AssetDefinition) -> Result<(), MintabilityError> { + if definition.mintable == Mintable::Once { + definition.mintable = Mintable::Not; + Ok(()) + } else { + Err(MintabilityError::ForbidMintOnMintable) + } } /// Assert that this asset is `mintable`. - fn assert_can_mint( - asset_definition: &AssetDefinition, - state_transaction: &mut StateTransaction<'_, '_>, - ) -> Result<(), Error> { + /// + /// Returns whether mintability changed. + fn assert_can_mint(asset_definition: &mut AssetDefinition) -> Result { match asset_definition.mintable { - Mintable::Infinitely => Ok(()), + Mintable::Infinitely => Ok(false), Mintable::Not => Err(Error::Mintability(MintabilityError::MintUnmintable)), Mintable::Once => { - let asset_definition_id = asset_definition.id.clone(); - let asset_definition = state_transaction - .world - .asset_definition_mut(&asset_definition_id)?; forbid_minting(asset_definition)?; - state_transaction.world.emit_events(Some( - AssetDefinitionEvent::MintabilityChanged(asset_definition_id), - )); - Ok(()) + Ok(true) } } } - pub(crate) fn expected_asset_type_numeric(asset_type: &AssetType) -> Result<(), TypeError> { - match asset_type { - AssetType::Numeric(_) => Ok(()), - other => Err(TypeError::NumericAssetTypeExpected(*other)), - } - } + #[cfg(test)] + mod test { + use iroha_data_model::{prelude::AssetDefinition, ParseError}; + use iroha_test_samples::gen_account_in; + + use crate::smartcontracts::isi::Registrable; - pub(crate) fn expected_asset_type_store(asset_type: &AssetType) -> Result<(), TypeError> { - match asset_type { - AssetType::Store => Ok(()), - other => Err(TypeError::NumericAssetTypeExpected(*other)), + #[test] + fn cannot_forbid_minting_on_asset_mintable_infinitely() -> Result<(), ParseError> { + let (authority, _authority_keypair) = gen_account_in("wonderland"); + let mut definition = AssetDefinition::new("test#hello".parse()?).build(&authority); + assert!(super::forbid_minting(&mut definition).is_err()); + Ok(()) } } } @@ -424,7 +398,7 @@ pub mod isi { pub mod query { use eyre::Result; use iroha_data_model::{ - asset::{Asset, AssetDefinition, AssetValue}, + asset::{Asset, AssetDefinition}, query::{ error::QueryExecutionFail as Error, predicate::{ @@ -433,36 +407,53 @@ pub mod query { }, }, }; - use iroha_primitives::json::Json; use super::*; use crate::{smartcontracts::ValidQuery, state::StateReadOnly}; - impl ValidQuery for FindAssets { - #[metrics(+"find_assets")] + impl ValidQuery for FindAssetsDefinitions { + #[metrics(+"find_asset_definitions")] fn execute( self, - filter: CompoundPredicate, + filter: CompoundPredicate, state_ro: &impl StateReadOnly, - ) -> Result, Error> { + ) -> Result, Error> { Ok(state_ro .world() - .assets_iter() - .filter(move |&asset| filter.applies(asset)) + .asset_definitions_iter() + .filter(move |&asset_definition| filter.applies(asset_definition)) .cloned()) } } - impl ValidQuery for FindAssetsDefinitions { - #[metrics(+"find_asset_definitions")] + + impl ValidSingularQuery for FindAssetDefinitionMetadata { + #[metrics(+"find_asset_definition_key_value_by_id_and_key")] + fn execute(&self, state_ro: &impl StateReadOnly) -> Result { + let id = &self.id; + let key = &self.key; + iroha_logger::trace!(%id, %key); + Ok(state_ro + .world() + .asset_definition(id)? + .metadata + .get(key) + .ok_or(FindError::MetadataKey(key.clone())) + .cloned() + .map(Into::into)?) + } + } + + impl ValidQuery for FindAssets { + #[metrics(+"find_assets")] fn execute( self, - filter: CompoundPredicate, + filter: CompoundPredicate, state_ro: &impl StateReadOnly, - ) -> Result, Error> { + ) -> Result, Error> { Ok(state_ro .world() - .asset_definitions_iter() - .filter(move |&asset_definition| filter.applies(asset_definition)) + .assets_iter() + .filter(move |&asset| filter.applies(asset)) .cloned()) } } @@ -471,50 +462,18 @@ pub mod query { #[metrics(+"find_asset_quantity_by_id")] fn execute(&self, state_ro: &impl StateReadOnly) -> Result { let id = &self.id; - iroha_logger::trace!(%id); - let value = state_ro + trace!(%id); + state_ro .world() .asset(id) + .map(|asset| asset.value) .map_err(|asset_err| { if let Err(definition_err) = state_ro.world().asset_definition(&id.definition) { Error::Find(definition_err) } else { asset_err } - })? - .value; - - match value { - AssetValue::Store(_) => Err(Error::Conversion( - "Can't get quantity for strore asset".to_string(), - )), - AssetValue::Numeric(numeric) => Ok(numeric), - } - } - } - - impl ValidSingularQuery for FindAssetMetadata { - #[metrics(+"find_asset_key_value_by_id_and_key")] - fn execute(&self, state_ro: &impl StateReadOnly) -> Result { - let id = &self.id; - let key = &self.key; - let asset = state_ro.world().asset(id).map_err(|asset_err| { - if let Err(definition_err) = state_ro.world().asset_definition(&id.definition) { - Error::Find(definition_err) - } else { - asset_err - } - })?; - iroha_logger::trace!(%id, %key); - let AssetValue::Store(store) = &asset.value else { - return Err(Error::Conversion("expected store, found other".to_owned())); - }; - - store - .get(key) - .ok_or_else(|| Error::Find(FindError::MetadataKey(key.clone()))) - .cloned() - .map(Into::into) + }) } } } diff --git a/crates/iroha_core/src/smartcontracts/isi/domain.rs b/crates/iroha_core/src/smartcontracts/isi/domain.rs index 7131c4ec2f2..f11b44fac49 100644 --- a/crates/iroha_core/src/smartcontracts/isi/domain.rs +++ b/crates/iroha_core/src/smartcontracts/isi/domain.rs @@ -4,7 +4,7 @@ use eyre::Result; use iroha_data_model::{prelude::*, query::error::FindError}; use iroha_telemetry::metrics; -use super::super::isi::prelude::*; +use crate::smartcontracts::isi::prelude::*; impl Registrable for iroha_data_model::domain::NewDomain { type Target = Domain; @@ -28,7 +28,6 @@ impl Registrable for iroha_data_model::domain::NewDomain { /// - transfer, etc. pub mod isi { use iroha_data_model::isi::error::{InstructionExecutionError, RepetitionError}; - use iroha_logger::prelude::*; use super::*; @@ -129,168 +128,6 @@ pub mod isi { } } - impl Execute for Register { - #[metrics(+"register_asset_definition")] - fn execute( - self, - authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, - ) -> Result<(), Error> { - let asset_definition = self.object.build(authority); - - let asset_definition_id = asset_definition.id().clone(); - if state_transaction - .world - .asset_definition(&asset_definition_id) - .is_ok() - { - return Err(RepetitionError { - instruction: InstructionType::Register, - id: IdBox::AssetDefinitionId(asset_definition_id), - } - .into()); - } - let _ = state_transaction - .world - .domain(&asset_definition_id.domain)?; - - state_transaction - .world - .asset_definitions - .insert(asset_definition_id.clone(), asset_definition.clone()); - - state_transaction - .world - .emit_events(Some(DomainEvent::AssetDefinition( - AssetDefinitionEvent::Created(asset_definition), - ))); - - Ok(()) - } - } - - impl Execute for Unregister { - #[metrics(+"unregister_asset_definition")] - fn execute( - self, - _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, - ) -> Result<(), Error> { - let asset_definition_id = self.object; - - let mut assets_to_remove = Vec::new(); - assets_to_remove.extend( - state_transaction - .world - .assets - .iter() - .filter(|(asset_id, _)| asset_id.definition == asset_definition_id) - .map(|(asset_id, _)| asset_id) - .cloned(), - ); - - let mut events = Vec::with_capacity(assets_to_remove.len() + 1); - for asset_id in assets_to_remove { - if state_transaction - .world - .assets - .remove(asset_id.clone()) - .is_none() - { - error!(%asset_id, "asset not found. This is a bug"); - } - - events.push(AssetEvent::Deleted(asset_id).into()); - } - - if state_transaction - .world - .asset_definitions - .remove(asset_definition_id.clone()) - .is_none() - { - return Err(FindError::AssetDefinition(asset_definition_id).into()); - } - let _ = state_transaction - .world - .domain(&asset_definition_id.domain)?; - - events.push(DataEvent::from(AssetDefinitionEvent::Deleted( - asset_definition_id, - ))); - - state_transaction.world.emit_events(events); - - Ok(()) - } - } - - impl Execute for SetKeyValue { - #[metrics(+"set_key_value_asset_definition")] - fn execute( - self, - _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, - ) -> Result<(), Error> { - let asset_definition_id = self.object; - - state_transaction - .world - .asset_definition_mut(&asset_definition_id) - .map_err(Error::from) - .map(|asset_definition| { - asset_definition - .metadata - .insert(self.key.clone(), self.value.clone()) - })?; - - state_transaction - .world - .emit_events(Some(AssetDefinitionEvent::MetadataInserted( - MetadataChanged { - target: asset_definition_id, - key: self.key, - value: self.value, - }, - ))); - - Ok(()) - } - } - - impl Execute for RemoveKeyValue { - #[metrics(+"remove_key_value_asset_definition")] - fn execute( - self, - _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, - ) -> Result<(), Error> { - let asset_definition_id = self.object; - - let value = state_transaction - .world - .asset_definition_mut(&asset_definition_id) - .and_then(|asset_definition| { - asset_definition - .metadata - .remove(&self.key) - .ok_or_else(|| FindError::MetadataKey(self.key.clone())) - })?; - - state_transaction - .world - .emit_events(Some(AssetDefinitionEvent::MetadataRemoved( - MetadataChanged { - target: asset_definition_id, - key: self.key, - value, - }, - ))); - - Ok(()) - } - } - impl Execute for SetKeyValue { #[metrics(+"set_domain_key_value")] fn execute( @@ -421,21 +258,4 @@ pub mod query { .map(Into::into) } } - - impl ValidSingularQuery for FindAssetDefinitionMetadata { - #[metrics(+"find_asset_definition_key_value_by_id_and_key")] - fn execute(&self, state_ro: &impl StateReadOnly) -> Result { - let id = &self.id; - let key = &self.key; - iroha_logger::trace!(%id, %key); - Ok(state_ro - .world() - .asset_definition(id)? - .metadata - .get(key) - .ok_or(FindError::MetadataKey(key.clone())) - .cloned() - .map(Into::into)?) - } - } } diff --git a/crates/iroha_core/src/smartcontracts/isi/mod.rs b/crates/iroha_core/src/smartcontracts/isi/mod.rs index 46140458ba6..eec820ee21c 100644 --- a/crates/iroha_core/src/smartcontracts/isi/mod.rs +++ b/crates/iroha_core/src/smartcontracts/isi/mod.rs @@ -75,7 +75,6 @@ impl Execute for RegisterBox { Self::Domain(isi) => isi.execute(authority, state_transaction), Self::Account(isi) => isi.execute(authority, state_transaction), Self::AssetDefinition(isi) => isi.execute(authority, state_transaction), - Self::Asset(isi) => isi.execute(authority, state_transaction), Self::Role(isi) => isi.execute(authority, state_transaction), Self::Trigger(isi) => isi.execute(authority, state_transaction), } @@ -94,7 +93,6 @@ impl Execute for UnregisterBox { Self::Domain(isi) => isi.execute(authority, state_transaction), Self::Account(isi) => isi.execute(authority, state_transaction), Self::AssetDefinition(isi) => isi.execute(authority, state_transaction), - Self::Asset(isi) => isi.execute(authority, state_transaction), Self::Role(isi) => isi.execute(authority, state_transaction), Self::Trigger(isi) => isi.execute(authority, state_transaction), } @@ -139,20 +137,7 @@ impl Execute for TransferBox { match self { Self::Domain(isi) => isi.execute(authority, state_transaction), Self::AssetDefinition(isi) => isi.execute(authority, state_transaction), - Self::Asset(isi) => isi.execute(authority, state_transaction), - } - } -} - -impl Execute for AssetTransferBox { - fn execute( - self, - authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, - ) -> std::prelude::v1::Result<(), Error> { - match self { Self::Numeric(isi) => isi.execute(authority, state_transaction), - Self::Store(isi) => isi.execute(authority, state_transaction), } } } @@ -167,7 +152,6 @@ impl Execute for SetKeyValueBox { Self::Domain(isi) => isi.execute(authority, state_transaction), Self::Account(isi) => isi.execute(authority, state_transaction), Self::AssetDefinition(isi) => isi.execute(authority, state_transaction), - Self::Asset(isi) => isi.execute(authority, state_transaction), Self::Trigger(isi) => isi.execute(authority, state_transaction), } } @@ -183,7 +167,6 @@ impl Execute for RemoveKeyValueBox { Self::Domain(isi) => isi.execute(authority, state_transaction), Self::Account(isi) => isi.execute(authority, state_transaction), Self::AssetDefinition(isi) => isi.execute(authority, state_transaction), - Self::Asset(isi) => isi.execute(authority, state_transaction), Self::Trigger(isi) => isi.execute(authority, state_transaction), } } @@ -252,34 +235,13 @@ mod tests { .execute(&SAMPLE_GENESIS_ACCOUNT_ID, &mut state_transaction)?; Register::account(Account::new(ALICE_ID.clone())) .execute(&SAMPLE_GENESIS_ACCOUNT_ID, &mut state_transaction)?; - Register::asset_definition(AssetDefinition::store(asset_definition_id)) + Register::asset_definition(AssetDefinition::new(asset_definition_id)) .execute(&SAMPLE_GENESIS_ACCOUNT_ID, &mut state_transaction)?; state_transaction.apply(); state_block.commit(); Ok(state) } - #[test] - async fn asset_store() -> Result<()> { - let kura = Kura::blank_kura_for_testing(); - let state = state_with_test_domains(&kura)?; - let mut state_block = state.block(); - let mut state_transaction = state_block.transaction(); - let account_id = ALICE_ID.clone(); - let asset_definition_id = "rose#wonderland".parse()?; - let asset_id = AssetId::new(asset_definition_id, account_id.clone()); - let key = "Bytes".parse::()?; - SetKeyValue::asset(asset_id.clone(), key.clone(), vec![1_u32, 2_u32, 3_u32]) - .execute(&account_id, &mut state_transaction)?; - let asset = state_transaction.world.asset(&asset_id)?; - let AssetValue::Store(store) = &asset.value else { - panic!("expected store asset"); - }; - let value = store.get(&key).cloned(); - assert_eq!(value, Some(vec![1_u32, 2_u32, 3_u32,].into())); - Ok(()) - } - #[test] async fn account_metadata() -> Result<()> { let kura = Kura::blank_kura_for_testing(); diff --git a/crates/iroha_core/src/smartcontracts/isi/query.rs b/crates/iroha_core/src/smartcontracts/isi/query.rs index 4fbaa74c1a7..16f0c32d86a 100644 --- a/crates/iroha_core/src/smartcontracts/isi/query.rs +++ b/crates/iroha_core/src/smartcontracts/isi/query.rs @@ -48,11 +48,8 @@ impl SortableQueryOutput for AssetDefinition { } impl SortableQueryOutput for Asset { - fn get_metadata_sorting_key(&self, key: &Name) -> Option { - match &self.value { - AssetValue::Numeric(_) => None, - AssetValue::Store(metadata) => metadata.get(key).cloned(), - } + fn get_metadata_sorting_key(&self, _key: &Name) -> Option { + None } } @@ -247,9 +244,6 @@ impl ValidQueryRequest { SingularQueryBox::FindAccountMetadata(q) => { SingularQueryOutputBox::from(q.execute(state)?) } - SingularQueryBox::FindAssetMetadata(q) => { - SingularQueryOutputBox::from(q.execute(state)?) - } SingularQueryBox::FindAssetDefinitionMetadata(q) => { SingularQueryOutputBox::from(q.execute(state)?) } @@ -361,26 +355,27 @@ mod tests { let domain = Domain::new(domain_id).build(&ALICE_ID); let account = Account::new(ALICE_ID.clone()).build(&ALICE_ID); let asset_definition_id = "rose#wonderland".parse().expect("Valid"); - let asset_definition = AssetDefinition::numeric(asset_definition_id).build(&ALICE_ID); + let asset_definition = AssetDefinition::new(asset_definition_id).build(&ALICE_ID); World::with([domain], [account], [asset_definition]) } - fn world_with_test_asset_with_metadata() -> World { - let asset_definition_id = "rose#wonderland" - .parse::() - .expect("Valid"); - let domain = Domain::new("wonderland".parse().expect("Valid")).build(&ALICE_ID); - let account = Account::new(ALICE_ID.clone()).build(&ALICE_ID); - let asset_definition = - AssetDefinition::numeric(asset_definition_id.clone()).build(&ALICE_ID); - - let mut store = Metadata::default(); - store.insert("Bytes".parse().expect("Valid"), vec![1_u32, 2_u32, 3_u32]); - let asset_id = AssetId::new(asset_definition_id, account.id().clone()); - let asset = Asset::new(asset_id, AssetValue::Store(store)); - - World::with_assets([domain], [account], [asset_definition], [asset]) - } + // FIXME: NFT + // fn world_with_test_asset_with_metadata() -> World { + // let asset_definition_id = "rose#wonderland" + // .parse::() + // .expect("Valid"); + // let domain = Domain::new("wonderland".parse().expect("Valid")).build(&ALICE_ID); + // let account = Account::new(ALICE_ID.clone()).build(&ALICE_ID); + // let asset_definition = + // AssetDefinition::new(asset_definition_id.clone()).build(&ALICE_ID); + // + // let mut store = Metadata::default(); + // store.insert("Bytes".parse().expect("Valid"), vec![1_u32, 2_u32, 3_u32]); + // let asset_id = AssetId::new(asset_definition_id, account.id().clone()); + // let asset = Asset::new(asset_id, AssetValue::Store(store)); + // + // World::with_assets([domain], [account], [asset_definition], [asset]) + // } fn world_with_test_account_with_metadata() -> Result { let mut metadata = Metadata::default(); @@ -391,7 +386,7 @@ mod tests { .with_metadata(metadata) .build(&ALICE_ID); let asset_definition_id = "rose#wonderland".parse().expect("Valid"); - let asset_definition = AssetDefinition::numeric(asset_definition_id).build(&ALICE_ID); + let asset_definition = AssetDefinition::new(asset_definition_id).build(&ALICE_ID); Ok(World::with([domain], [account], [asset_definition])) } @@ -466,19 +461,6 @@ mod tests { Ok(state) } - #[test] - async fn asset_store() -> Result<()> { - let kura = Kura::blank_kura_for_testing(); - let query_handle = LiveQueryStore::start_test(); - let state = State::new(world_with_test_asset_with_metadata(), kura, query_handle); - - let asset_definition_id = "rose#wonderland".parse()?; - let asset_id = AssetId::new(asset_definition_id, ALICE_ID.clone()); - let bytes = FindAssetMetadata::new(asset_id, "Bytes".parse()?).execute(&state.view())?; - assert_eq!(Json::from(vec![1_u32, 2_u32, 3_u32,]), bytes,); - Ok(()) - } - #[test] async fn account_metadata() -> Result<()> { let kura = Kura::blank_kura_for_testing(); @@ -672,7 +654,7 @@ mod tests { .build(&ALICE_ID); let account = Account::new(ALICE_ID.clone()).build(&ALICE_ID); let asset_definition_id = "rose#wonderland".parse()?; - let asset_definition = AssetDefinition::numeric(asset_definition_id).build(&ALICE_ID); + let asset_definition = AssetDefinition::new(asset_definition_id).build(&ALICE_ID); let query_handle = LiveQueryStore::start_test(); State::new( World::with([domain], [account], [asset_definition]), diff --git a/crates/iroha_core/src/state.rs b/crates/iroha_core/src/state.rs index 6eb0c7e1fa1..9e0f4b8bcf2 100644 --- a/crates/iroha_core/src/state.rs +++ b/crates/iroha_core/src/state.rs @@ -884,17 +884,13 @@ impl WorldTransaction<'_, '_> { /// # Errors /// - There is no account with such name. #[allow(clippy::missing_panics_doc)] - pub fn asset_or_insert( - &mut self, - asset_id: AssetId, - default_asset_value: impl Into, - ) -> Result<&mut Asset, Error> { + pub fn asset_or_insert(&mut self, asset_id: AssetId) -> Result<&mut Asset, Error> { self.domain(&asset_id.definition.domain)?; self.asset_definition(&asset_id.definition)?; self.account(&asset_id.account)?; if self.assets.get(&asset_id).is_none() { - let asset = Asset::new(asset_id.clone(), default_asset_value.into()); + let asset = Asset::new(asset_id.clone(), Numeric::ZERO); Self::emit_events_impl( &mut self.triggers, diff --git a/crates/iroha_core/src/sumeragi/main_loop.rs b/crates/iroha_core/src/sumeragi/main_loop.rs index 050c95c1d66..12429794180 100644 --- a/crates/iroha_core/src/sumeragi/main_loop.rs +++ b/crates/iroha_core/src/sumeragi/main_loop.rs @@ -1500,10 +1500,10 @@ mod tests { let block = { let mut state_block = state.block(); // Making two transactions that have the same instruction - let create_asset_definition1 = Register::asset_definition(AssetDefinition::numeric( + let create_asset_definition1 = Register::asset_definition(AssetDefinition::new( "xor1#wonderland".parse().expect("Valid"), )); - let create_asset_definition2 = Register::asset_definition(AssetDefinition::numeric( + let create_asset_definition2 = Register::asset_definition(AssetDefinition::new( "xor2#wonderland".parse().expect("Valid"), )); diff --git a/crates/iroha_data_model/src/asset.rs b/crates/iroha_data_model/src/asset.rs index f0edc5dc68e..eb7275595ed 100644 --- a/crates/iroha_data_model/src/asset.rs +++ b/crates/iroha_data_model/src/asset.rs @@ -1,14 +1,12 @@ //! This module contains [`Asset`] structure, it's implementation and related traits and //! instructions implementations. #[cfg(not(feature = "std"))] -use alloc::{collections::btree_map, format, string::String, vec::Vec}; +use alloc::{format, string::String, vec::Vec}; use core::{fmt, str::FromStr}; -#[cfg(feature = "std")] -use std::collections::btree_map; use derive_more::{Constructor, DebugCustom, Display}; use iroha_data_model_derive::{model, IdEqOrdHash}; -use iroha_primitives::numeric::{Numeric, NumericSpec, NumericSpecParseError}; +use iroha_primitives::numeric::{Numeric, NumericSpec}; use iroha_schema::IntoSchema; use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; @@ -20,14 +18,9 @@ use crate::{ Identifiable, Name, ParseError, Registered, }; -/// [`AssetTotalQuantityMap`] provides an API to work with collection of key([`AssetDefinitionId`])-value([`AssetValue`]) -/// pairs. -pub type AssetTotalQuantityMap = btree_map::BTreeMap; - #[model] mod model { use getset::{CopyGetters, Getters}; - use iroha_macro::FromVariant; use super::*; @@ -106,7 +99,7 @@ mod model { Serialize, IntoSchema, )] - #[display(fmt = "{id} {type_}{mintable}")] + #[display(fmt = "{id} {spec}{mintable}")] #[allow(clippy::multiple_inherent_impl)] #[ffi_type] pub struct AssetDefinition { @@ -114,8 +107,7 @@ mod model { pub id: AssetDefinitionId, /// Type of [`AssetValue`] #[getset(get_copy = "pub")] - #[serde(rename = "type")] - pub type_: AssetType, + pub spec: NumericSpec, /// Is the asset mintable #[getset(get_copy = "pub")] pub mintable: Mintable, @@ -155,22 +147,21 @@ mod model { pub id: AssetId, /// Asset's Quantity. #[getset(get = "pub")] - pub value: AssetValue, + pub value: Numeric, } /// Builder which can be submitted in a transaction to create a new [`AssetDefinition`] #[derive( Debug, Display, Clone, IdEqOrdHash, Decode, Encode, Deserialize, Serialize, IntoSchema, )] - #[display(fmt = "{id} {mintable}{type_}")] + #[display(fmt = "{id} {spec}{mintable}")] #[serde(rename = "AssetDefinition")] #[ffi_type] pub struct NewAssetDefinition { /// The identification associated with the asset definition builder. pub id: AssetDefinitionId, /// The type value associated with the asset definition builder. - #[serde(rename = "type")] - pub type_: AssetType, + pub spec: NumericSpec, /// The mintablility associated with the asset definition builder. pub mintable: Mintable, /// IPFS link to the [`AssetDefinition`] logo @@ -178,65 +169,10 @@ mod model { /// Metadata associated with the asset definition builder. pub metadata: Metadata, } - /// Asset's inner value type. - #[derive( - Debug, - Display, - Clone, - Copy, - PartialEq, - Eq, - PartialOrd, - Ord, - Decode, - Encode, - DeserializeFromStr, - SerializeDisplay, - IntoSchema, - )] - #[ffi_type] - #[repr(u8)] - pub enum AssetType { - /// Asset's qualitative value. - #[display(fmt = "{_0}")] - Numeric(NumericSpec), - /// Asset's key-value structured data. - #[display(fmt = "Store")] - Store, - } - - /// Asset's inner value. - #[derive( - Debug, - Display, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - FromVariant, - Decode, - Encode, - Deserialize, - Serialize, - IntoSchema, - )] - #[ffi_type] - pub enum AssetValue { - /// Asset's qualitative value. - #[display(fmt = "{_0}")] - Numeric( - #[skip_from] - #[skip_try_from] - Numeric, - ), - /// Asset's key-value structured data. - Store(Metadata), - } /// An assets mintability scheme. `Infinitely` means elastic /// supply. `Once` is what you want to use. Don't use `Not` explicitly - /// outside of smartcontracts. + /// outside smartcontracts. #[derive( Debug, Display, @@ -268,37 +204,12 @@ mod model { } } -/// Error occurred while parsing `AssetType` -#[derive(Debug, displaydoc::Display, Clone)] -#[cfg_attr(feature = "std", derive(thiserror::Error))] -#[repr(u8)] -pub enum AssetTypeParseError { - /// `AssetType` should be either `Store` or `Numeric` - WrongVariant, - /// Error occurred while parsing `Numeric` variant: {_0} - Numeric(#[cfg_attr(feature = "std", source)] NumericSpecParseError), -} - impl AssetDefinition { /// Construct builder for [`AssetDefinition`] identifiable by [`Id`]. #[must_use] #[inline] - pub fn new(id: AssetDefinitionId, type_: AssetType) -> ::With { - ::With::new(id, type_) - } - - /// Construct builder for [`AssetDefinition`] identifiable by [`Id`]. - #[must_use] - #[inline] - pub fn numeric(id: AssetDefinitionId) -> ::With { - ::With::new(id, AssetType::Numeric(NumericSpec::default())) - } - - /// Construct builder for [`AssetDefinition`] identifiable by [`Id`]. - #[must_use] - #[inline] - pub fn store(id: AssetDefinitionId) -> ::With { - ::With::new(id, AssetType::Store) + pub fn new(id: AssetDefinitionId) -> ::With { + ::With::new(id) } } @@ -314,26 +225,31 @@ impl AssetId { impl Asset { /// Constructor - pub fn new(id: AssetId, value: impl Into) -> ::With { - Self { - id, - value: value.into(), - } + pub fn new(id: AssetId, value: Numeric) -> ::With { + Self { id, value } } } impl NewAssetDefinition { /// Create a [`NewAssetDefinition`], reserved for internal use. - fn new(id: AssetDefinitionId, type_: AssetType) -> Self { + fn new(id: AssetDefinitionId) -> Self { Self { id, - type_, + spec: NumericSpec::unconstrained(), mintable: Mintable::Infinitely, logo: None, metadata: Metadata::default(), } } + /// Set the [`NumericSpec`] of the asset definition. + #[inline] + #[must_use] + pub fn with_numeric_spec(mut self, spec: NumericSpec) -> Self { + self.spec = spec; + self + } + /// Set mintability to [`Mintable::Once`] #[inline] #[must_use] @@ -364,29 +280,6 @@ impl HasMetadata for AssetDefinition { } } -impl AssetValue { - /// Returns the asset type as a string. - pub const fn type_(&self) -> AssetType { - match *self { - Self::Numeric(numeric) => AssetType::Numeric(NumericSpec::fractional(numeric.scale())), - Self::Store(_) => AssetType::Store, - } - } - /// Returns true if this value is zero, false if it contains [`Metadata`] or positive value - pub const fn is_zero_value(&self) -> bool { - match *self { - Self::Numeric(q) => q.is_zero(), - Self::Store(_) => false, - } - } -} - -impl> From for AssetValue { - fn from(value: T) -> Self { - Self::Numeric(value.into()) - } -} - /// Asset Definition Identification is represented by `name#domain_name` string. impl FromStr for AssetDefinitionId { type Err = ParseError; @@ -454,21 +347,6 @@ impl FromStr for AssetId { } } -impl FromStr for AssetType { - type Err = AssetTypeParseError; - - fn from_str(s: &str) -> Result { - match s { - "Store" => Ok(Self::Store), - s if s.starts_with("Numeric") => s - .parse::() - .map(Self::Numeric) - .map_err(AssetTypeParseError::Numeric), - _ => Err(AssetTypeParseError::WrongVariant), - } - } -} - impl HasMetadata for NewAssetDefinition { fn metadata(&self) -> &Metadata { &self.metadata @@ -486,8 +364,7 @@ impl Registered for AssetDefinition { /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { pub use super::{ - Asset, AssetDefinition, AssetDefinitionId, AssetId, AssetType, AssetValue, Mintable, - NewAssetDefinition, + Asset, AssetDefinition, AssetDefinitionId, AssetId, Mintable, NewAssetDefinition, }; } diff --git a/crates/iroha_data_model/src/events/data/events.rs b/crates/iroha_data_model/src/events/data/events.rs index 7f94a75da30..f12fdcb264a 100644 --- a/crates/iroha_data_model/src/events/data/events.rs +++ b/crates/iroha_data_model/src/events/data/events.rs @@ -103,7 +103,6 @@ mod asset { pub use self::model::*; use super::*; - type AssetMetadataChanged = MetadataChanged; type AssetDefinitionMetadataChanged = MetadataChanged; data_event! { @@ -116,10 +115,6 @@ mod asset { Added(AssetChanged), #[has_origin(asset_changed => &asset_changed.asset)] Removed(AssetChanged), - #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataInserted(AssetMetadataChanged), - #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataRemoved(AssetMetadataChanged), } } @@ -164,7 +159,7 @@ mod asset { #[ffi_type] pub struct AssetChanged { pub asset: AssetId, - pub amount: AssetValue, + pub amount: Numeric, } /// [`Self`] represents updated total asset quantity. diff --git a/crates/iroha_data_model/src/events/data/filters.rs b/crates/iroha_data_model/src/events/data/filters.rs index 20dbf6e0d3d..14dbdd93da6 100644 --- a/crates/iroha_data_model/src/events/data/filters.rs +++ b/crates/iroha_data_model/src/events/data/filters.rs @@ -740,7 +740,7 @@ mod tests { owned_by: domain_owner_id, }; let account = Account::new(account_id.clone()).into_account(); - let asset = Asset::new(asset_id.clone(), 0_u32); + let asset = Asset::new(asset_id.clone(), Numeric::ZERO); // Create three events with three levels of nesting // the first one is just a domain event @@ -751,7 +751,7 @@ mod tests { let asset_created = DomainEvent::Account(AccountEvent::Asset(AssetEvent::Created(asset))).into(); - // test how the differently nested filters with with the events + // test how the differently nested filters with the events let domain_filter = DataEventFilter::Domain(DomainEventFilter::new().for_domain(domain_id)); let account_filter = DataEventFilter::Account(AccountEventFilter::new().for_account(account_id)); diff --git a/crates/iroha_data_model/src/isi.rs b/crates/iroha_data_model/src/isi.rs index 4bf8ec295a3..60778cb0e55 100644 --- a/crates/iroha_data_model/src/isi.rs +++ b/crates/iroha_data_model/src/isi.rs @@ -139,25 +139,21 @@ impl_instruction! { SetKeyValue, SetKeyValue, SetKeyValue, - SetKeyValue, SetKeyValue, RemoveKeyValue, RemoveKeyValue, RemoveKeyValue, - RemoveKeyValue, RemoveKeyValue, Register, Register, Register, Register, - Register, Register, Register, Unregister, Unregister, Unregister, Unregister, - Unregister, Unregister, Unregister, Mint, @@ -167,7 +163,6 @@ impl_instruction! { Transfer, Transfer, Transfer, - Transfer, Grant, Grant, Grant, @@ -192,7 +187,7 @@ mod transparent { use iroha_primitives::json::Json; use super::*; - use crate::{account::NewAccount, domain::NewDomain, metadata::Metadata}; + use crate::{account::NewAccount, domain::NewDomain}; macro_rules! isi { ($($meta:meta)* $item:item) => { @@ -311,17 +306,6 @@ mod transparent { } } - impl SetKeyValue { - /// Constructs a new [`SetKeyValue`] for an [`Asset`] with the given `key` and `value`. - pub fn asset(asset_id: AssetId, key: Name, value: impl Into) -> Self { - Self { - object: asset_id, - key, - value: value.into(), - } - } - } - impl SetKeyValue { /// Constructs a new [`SetKeyValue`] for a [`Trigger`] with the given `key` and `value`. pub fn trigger(trigger_id: TriggerId, key: Name, value: impl Into) -> Self { @@ -347,7 +331,6 @@ mod transparent { SetKeyValue | SetKeyValue | SetKeyValue | - SetKeyValue | SetKeyValue => SetKeyValueBox => InstructionBox[SetKeyValue], => SetKeyValueBoxRef<'a> => InstructionBoxRef<'a>[SetKeyValue] @@ -393,16 +376,6 @@ mod transparent { } } - impl RemoveKeyValue { - /// Constructs a new [`RemoveKeyValue`] for an [`Asset`] with the given `key`. - pub fn asset(asset_id: AssetId, key: Name) -> Self { - Self { - object: asset_id, - key, - } - } - } - impl RemoveKeyValue { /// Constructs a new [`RemoveKeyValue`] for an [`Asset`] with the given `key`. pub fn trigger(trigger_id: TriggerId, key: Name) -> Self { @@ -427,7 +400,6 @@ mod transparent { RemoveKeyValue | RemoveKeyValue | RemoveKeyValue | - RemoveKeyValue | RemoveKeyValue => RemoveKeyValueBox => InstructionBox[RemoveKeyValue], => RemoveKeyValueBoxRef<'a> => InstructionBoxRef<'a>[RemoveKeyValue] @@ -474,13 +446,6 @@ mod transparent { } } - impl Register { - /// Constructs a new [`Register`] for an [`Asset`]. - pub fn asset(new_asset: Asset) -> Self { - Self { object: new_asset } - } - } - impl Register { /// Constructs a new [`Register`] for a [`Role`]. pub fn role(new_role: NewRole) -> Self { @@ -512,7 +477,6 @@ mod transparent { Register | Register | Register | - Register | Register | Register => RegisterBox => InstructionBox[Register], @@ -542,7 +506,6 @@ mod transparent { Unregister | Unregister | Unregister | - Unregister | Unregister | Unregister => UnregisterBox => InstructionBox[Unregister], @@ -579,13 +542,6 @@ mod transparent { } } - impl Unregister { - /// Constructs a new [`Unregister`] for an [`Asset`]. - pub fn asset(asset_id: AssetId) -> Self { - Self { object: asset_id } - } - } - impl Unregister { /// Constructs a new [`Unregister`] for a [`Role`]. pub fn role(role_id: RoleId) -> Self { @@ -751,17 +707,6 @@ mod transparent { } } - impl Transfer { - /// Constructs a new [`Transfer`] for an [`Asset`] of [`Store`] type. - pub fn asset_store(asset_id: AssetId, to: AccountId) -> Self { - Self { - source: asset_id, - object: Metadata::default(), - destination: to, - } - } - } - impl_display! { Transfer where @@ -777,16 +722,10 @@ mod transparent { destination, } - impl_into_box! { - Transfer | Transfer - => AssetTransferBox => TransferBox[Asset], - => AssetTransferBoxRef<'a> => TransferBoxRef<'a>[Asset] - } - impl_into_box! { Transfer | Transfer | - Transfer | Transfer + Transfer => TransferBox => InstructionBox[Transfer], => TransferBoxRef<'a> => InstructionBoxRef<'a>[Transfer] } @@ -1034,8 +973,6 @@ isi_box! { Account(SetKeyValue), /// Set key value for [`AssetDefinition`]. AssetDefinition(SetKeyValue), - /// Set key value for [`Asset`]. - Asset(SetKeyValue), /// Set key value for [`Trigger`]. Trigger(SetKeyValue), } @@ -1055,8 +992,6 @@ isi_box! { Account(RemoveKeyValue), /// Remove key value from [`AssetDefinition`]. AssetDefinition(RemoveKeyValue), - /// Remove key value from [`Asset`]. - Asset(RemoveKeyValue), /// Remove key value for [`Trigger`]. Trigger(RemoveKeyValue), } @@ -1078,8 +1013,6 @@ isi_box! { Account(Register), /// Register [`AssetDefinition`]. AssetDefinition(Register), - /// Register [`Asset`]. - Asset(Register), /// Register [`Role`]. Role(Register), /// Register [`Trigger`]. @@ -1103,8 +1036,6 @@ isi_box! { Account(Unregister), /// Unregister [`AssetDefinition`]. AssetDefinition(Unregister), - /// Unregister [`Asset`]. - Asset(Unregister), /// Unregister [`Role`]. Role(Unregister), /// Unregister [`Trigger`]. @@ -1154,24 +1085,8 @@ isi_box! { Domain(Transfer), /// Transfer [`AssetDefinition`] to another [`Account`]. AssetDefinition(Transfer), - /// Transfer [`Asset`] to another [`Account`]. - #[enum_ref(transparent)] - Asset(AssetTransferBox), - } -} - -isi_box! { - #[strum_discriminants( - vis(pub(crate)), - name(AssetTransferType), - derive(Encode), - )] - /// Enum with all supported [`Transfer`] instructions related to [`Asset`]. - pub enum AssetTransferBox { /// Transfer [`Asset`] of [`Numeric`] type. Numeric(Transfer), - /// Transfer [`Asset`] of [`Store`] type. - Store(Transfer), } } @@ -1225,7 +1140,7 @@ pub mod error { pub use self::model::*; use super::InstructionType; use crate::{ - asset::AssetType, + prelude::NumericSpec, query::error::{FindError, QueryExecutionFail}, IdBox, }; @@ -1359,14 +1274,8 @@ pub mod error { #[cfg_attr(feature = "std", derive(thiserror::Error))] #[ffi_type] pub enum TypeError { - /// Asset Ids correspond to assets with different underlying types, {0} - AssetType(#[cfg_attr(feature = "std", source)] Mismatch), - /// Numeric asset value type was expected, received: {0} - NumericAssetTypeExpected( - #[skip_from] - #[skip_try_from] - AssetType, - ), + /// Asset Ids correspond to assets with different underlying specs, {0} + NumericSpec(#[cfg_attr(feature = "std", source)] Mismatch), } /// Math error, which occurs during instruction execution @@ -1495,9 +1404,9 @@ pub mod error { /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { pub use super::{ - AssetTransferBox, Burn, BurnBox, CustomInstruction, ExecuteTrigger, Grant, GrantBox, - InstructionBox, Log, Mint, MintBox, Register, RegisterBox, RemoveKeyValue, - RemoveKeyValueBox, Revoke, RevokeBox, SetKeyValue, SetKeyValueBox, SetParameter, Transfer, - TransferBox, Unregister, UnregisterBox, Upgrade, + Burn, BurnBox, CustomInstruction, ExecuteTrigger, Grant, GrantBox, InstructionBox, Log, + Mint, MintBox, Register, RegisterBox, RemoveKeyValue, RemoveKeyValueBox, Revoke, RevokeBox, + SetKeyValue, SetKeyValueBox, SetParameter, Transfer, TransferBox, Unregister, + UnregisterBox, Upgrade, }; } diff --git a/crates/iroha_data_model/src/lib.rs b/crates/iroha_data_model/src/lib.rs index 7d0de719e22..d5fa45805cf 100644 --- a/crates/iroha_data_model/src/lib.rs +++ b/crates/iroha_data_model/src/lib.rs @@ -71,13 +71,11 @@ mod seal { SetKeyValue, SetKeyValue, SetKeyValue, - SetKeyValue, SetKeyValue, RemoveKeyValue, RemoveKeyValue, RemoveKeyValue, - RemoveKeyValue, RemoveKeyValue, Register, @@ -105,7 +103,6 @@ mod seal { Transfer, Transfer, Transfer, - Transfer, Grant, Grant, @@ -128,7 +125,6 @@ mod seal { FindAssets, FindAssetsDefinitions, FindAssetQuantityById, - FindAssetMetadata, FindAssetDefinitionMetadata, FindDomains, FindDomainMetadata, diff --git a/crates/iroha_data_model/src/query/mod.rs b/crates/iroha_data_model/src/query/mod.rs index c2ed143790f..574f2ca67f0 100644 --- a/crates/iroha_data_model/src/query/mod.rs +++ b/crates/iroha_data_model/src/query/mod.rs @@ -138,7 +138,6 @@ mod model { FindDomainMetadata(FindDomainMetadata), FindAccountMetadata(FindAccountMetadata), - FindAssetMetadata(FindAssetMetadata), FindAssetDefinitionMetadata(FindAssetDefinitionMetadata), FindTriggerMetadata(FindTriggerMetadata), } @@ -572,7 +571,6 @@ impl_iter_queries! { impl_singular_queries! { FindAccountMetadata => Json, FindAssetQuantityById => Numeric, - FindAssetMetadata => Json, FindAssetDefinitionMetadata => Json, FindDomainMetadata => Json, FindParameters => crate::parameter::Parameters, @@ -765,18 +763,6 @@ pub mod asset { pub id: AssetId, } - /// [`FindAssetMetadata`] Iroha Query gets [`AssetId`] and key as input and finds [`MetadataValue`] - /// of the key-value pair stored in this asset. - #[derive(Display)] - #[display(fmt = "Find metadata value with `{key}` key in `{id}` asset")] - #[ffi_type] - pub struct FindAssetMetadata { - /// `Id` of an [`Asset`] acting as [`Store`](crate::asset::AssetValue::Store). - pub id: AssetId, - /// The key of the key-value pair stored in the asset. - pub key: Name, - } - /// [`FindAssetDefinitionMetadata`] Iroha Query gets [`AssetDefinitionId`] and key as input and finds [`MetadataValue`] /// of the key-value pair stored in this asset definition. #[derive(Display)] @@ -793,8 +779,7 @@ pub mod asset { /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { pub use super::{ - FindAssetDefinitionMetadata, FindAssetMetadata, FindAssetQuantityById, FindAssets, - FindAssetsDefinitions, + FindAssetDefinitionMetadata, FindAssetQuantityById, FindAssets, FindAssetsDefinitions, }; } } diff --git a/crates/iroha_data_model/src/query/predicate/predicate_atoms/asset.rs b/crates/iroha_data_model/src/query/predicate/predicate_atoms/asset.rs index 60f80883728..ed8d5133ec4 100644 --- a/crates/iroha_data_model/src/query/predicate/predicate_atoms/asset.rs +++ b/crates/iroha_data_model/src/query/predicate/predicate_atoms/asset.rs @@ -7,9 +7,9 @@ use iroha_schema::IntoSchema; use iroha_version::{Decode, Encode}; use serde::{Deserialize, Serialize}; -use super::impl_predicate_box; +use super::{impl_predicate_box, NumericPredicateBox}; use crate::{ - asset::{Asset, AssetDefinition, AssetDefinitionId, AssetId, AssetValue}, + asset::{Asset, AssetDefinition, AssetDefinitionId, AssetId}, query::{ predicate::{ predicate_ast_extensions::AstPredicateExt as _, @@ -58,7 +58,7 @@ pub enum AssetPredicateBox { /// Checks if a predicate applies to the ID of the input. Id(AssetIdPredicateBox), /// Checks if a predicate applies to the value of the input. - Value(AssetValuePredicateBox), + Value(NumericPredicateBox), } impl_predicate_box!(Asset: AssetPredicateBox); @@ -72,22 +72,6 @@ impl EvaluatePredicate for AssetPredicateBox { } } -/// A predicate that can be applied to an [`AssetValue`]. -#[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] -pub enum AssetValuePredicateBox { - // TODO: populate - // FIX: Remove all `#[allow(unreachable_patterns)]` from all use sites - // once some variants are added into this enum -} - -impl_predicate_box!(AssetValue: AssetValuePredicateBox); - -impl EvaluatePredicate for AssetValuePredicateBox { - fn applies(&self, _input: &AssetValue) -> bool { - match *self {} - } -} - /// A predicate that can be applied to an [`AssetId`]. #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub enum AssetIdPredicateBox { @@ -144,6 +128,6 @@ pub mod prelude { //! Re-export all predicate boxes for a glob import `(::*)` pub use super::{ AssetDefinitionIdPredicateBox, AssetDefinitionPredicateBox, AssetIdPredicateBox, - AssetPredicateBox, AssetValuePredicateBox, + AssetPredicateBox, }; } diff --git a/crates/iroha_data_model/src/query/predicate/predicate_atoms/mod.rs b/crates/iroha_data_model/src/query/predicate/predicate_atoms/mod.rs index 4f1b3458491..b765b32276a 100644 --- a/crates/iroha_data_model/src/query/predicate/predicate_atoms/mod.rs +++ b/crates/iroha_data_model/src/query/predicate/predicate_atoms/mod.rs @@ -20,6 +20,7 @@ pub mod trigger; use alloc::{format, string::String, vec::Vec}; use iroha_crypto::PublicKey; +use iroha_primitives::numeric::{Numeric, NumericSpec}; use iroha_schema::IntoSchema; use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; @@ -143,6 +144,38 @@ where } } +/// A predicate that can be applied to a [`Numeric`]. +#[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] +pub enum NumericPredicateBox { + /// Checks if the numeric value matches the given [`NumericSpec`]. + MatchesSpec(NumericSpec), + /// Checks if the numeric value is equal to the expected value. + Equals(Numeric), + /// Checks if the numeric value is less than the expected value. + LessThan(Numeric), + /// Checks if the numeric value is less than or equal to the expected value. + LessThanOrEquals(Numeric), + /// Checks if the numeric value is greater than the expected value. + GreaterThan(Numeric), + /// Checks if the numeric value is greater than or equal to the expected value. + GreaterThanOrEquals(Numeric), +} + +impl_predicate_box!(Numeric: NumericPredicateBox); + +impl EvaluatePredicate for NumericPredicateBox { + fn applies(&self, input: &Numeric) -> bool { + match *self { + NumericPredicateBox::MatchesSpec(expected) => expected.check(input).is_ok(), + NumericPredicateBox::Equals(expected) => input == &expected, + NumericPredicateBox::LessThan(expected) => input < &expected, + NumericPredicateBox::LessThanOrEquals(expected) => input <= &expected, + NumericPredicateBox::GreaterThan(expected) => input > &expected, + NumericPredicateBox::GreaterThanOrEquals(expected) => input >= &expected, + } + } +} + /// A predicate that can be applied to [`Metadata`]. #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] pub enum MetadataPredicateBox { @@ -182,6 +215,7 @@ pub mod prelude { pub use super::{ account::prelude::*, asset::prelude::*, block::prelude::*, domain::prelude::*, parameter::prelude::*, peer::prelude::*, permission::prelude::*, role::prelude::*, - trigger::prelude::*, MetadataPredicateBox, PublicKeyPredicateBox, StringPredicateBox, + trigger::prelude::*, MetadataPredicateBox, NumericPredicateBox, PublicKeyPredicateBox, + StringPredicateBox, }; } diff --git a/crates/iroha_data_model/src/query/predicate/projectors.rs b/crates/iroha_data_model/src/query/predicate/projectors.rs index 4fe3d194f8d..a9bd4cb3b25 100644 --- a/crates/iroha_data_model/src/query/predicate/projectors.rs +++ b/crates/iroha_data_model/src/query/predicate/projectors.rs @@ -16,7 +16,7 @@ use crate::{ account::{AccountIdPredicateBox, AccountPredicateBox}, asset::{ AssetDefinitionIdPredicateBox, AssetDefinitionPredicateBox, AssetIdPredicateBox, - AssetPredicateBox, AssetValuePredicateBox, + AssetPredicateBox, }, block::{ BlockHashPredicateBox, CommittedTransactionPredicateBox, @@ -26,7 +26,7 @@ use crate::{ domain::{DomainIdPredicateBox, DomainPredicateBox}, role::{RoleIdPredicateBox, RolePredicateBox}, trigger::{TriggerIdPredicateBox, TriggerPredicateBox}, - MetadataPredicateBox, PublicKeyPredicateBox, StringPredicateBox, + MetadataPredicateBox, NumericPredicateBox, PublicKeyPredicateBox, StringPredicateBox, }, predicate_combinators::{AndAstPredicate, NotAstPredicate, OrAstPredicate}, }, @@ -182,7 +182,7 @@ proj!(AssetDefinitionMetadataProjector(AssetDefinitionMetadataProjection): Metad // projections on Asset proj!(AssetIdProjector(AssetIdProjection): AssetIdPredicateBox => AssetPredicateBox::Id); -proj!(AssetValueProjector(AssetValueProjection): AssetValuePredicateBox => AssetPredicateBox::Value); +proj!(AssetValueProjector(AssetValueProjection): NumericPredicateBox => AssetPredicateBox::Value); // projections on DomainId proj!(DomainIdNameProjector(DomainIdNameProjection): StringPredicateBox => DomainIdPredicateBox::Name); diff --git a/crates/iroha_data_model/src/query/predicate/prototypes/asset.rs b/crates/iroha_data_model/src/query/predicate/prototypes/asset.rs index aa48f671363..d64ea7f996b 100644 --- a/crates/iroha_data_model/src/query/predicate/prototypes/asset.rs +++ b/crates/iroha_data_model/src/query/predicate/prototypes/asset.rs @@ -1,15 +1,13 @@ //! Account-related prototypes, mirroring types in [`crate::asset`]. -use core::marker::PhantomData; - -use super::{impl_prototype, MetadataPrototype, StringPrototype}; +use super::{impl_prototype, MetadataPrototype, NumericPrototype, StringPrototype}; use crate::{ asset::{AssetDefinitionId, AssetId}, query::{ predicate::{ predicate_atoms::asset::{ AssetDefinitionIdPredicateBox, AssetDefinitionPredicateBox, AssetIdPredicateBox, - AssetPredicateBox, AssetValuePredicateBox, + AssetPredicateBox, }, projectors::{ AssetDefinitionIdDomainIdProjector, AssetDefinitionIdNameProjector, @@ -85,15 +83,7 @@ pub struct AssetPrototype { /// Build a predicate on ID of this [`crate::asset::Asset`] pub id: AssetIdPrototype>, /// Build a predicate on value of this [`crate::asset::Asset`] - pub value: AssetValuePrototype>, + pub value: NumericPrototype>, } impl_prototype!(AssetPrototype: AssetPredicateBox); - -/// A prototype of [`crate::asset::AssetValue`] for predicate construction. -#[derive(Default, Copy, Clone)] -pub struct AssetValuePrototype { - phantom: PhantomData, -} - -impl_prototype!(AssetValuePrototype: AssetValuePredicateBox); diff --git a/crates/iroha_data_model/src/query/predicate/prototypes/mod.rs b/crates/iroha_data_model/src/query/predicate/prototypes/mod.rs index 0bede28ec3c..8c65ef62419 100644 --- a/crates/iroha_data_model/src/query/predicate/prototypes/mod.rs +++ b/crates/iroha_data_model/src/query/predicate/prototypes/mod.rs @@ -17,10 +17,11 @@ use alloc::string::String; use core::marker::PhantomData; use iroha_crypto::PublicKey; +use iroha_primitives::numeric::{Numeric, NumericSpec}; use super::{projectors::ObjectProjector, AstPredicate, HasPrototype}; use crate::query::predicate::predicate_atoms::{ - MetadataPredicateBox, PublicKeyPredicateBox, StringPredicateBox, + MetadataPredicateBox, NumericPredicateBox, PublicKeyPredicateBox, StringPredicateBox, }; macro_rules! impl_prototype { @@ -90,6 +91,52 @@ where } } +/// A prototype of [`Numeric`] for predicate construction. +#[derive(Default, Copy, Clone)] +pub struct NumericPrototype { + phantom: PhantomData, +} + +impl_prototype!(NumericPrototype: NumericPredicateBox); + +impl NumericPrototype +where + Projector: ObjectProjector, +{ + /// Creates a predicate that checks if the numeric value matches the expected specification. + pub fn matches_spec( + &self, + expected: NumericSpec, + ) -> Projector::ProjectedPredicate { + Projector::project_predicate(NumericPredicateBox::MatchesSpec(expected)) + } + + /// Creates a predicate that checks if the numeric value is equal to the expected value. + pub fn eq(&self, expected: Numeric) -> Projector::ProjectedPredicate { + Projector::project_predicate(NumericPredicateBox::Equals(expected)) + } + + /// Creates a predicate that checks if the numeric value is less than the expected value. + pub fn lt(&self, expected: Numeric) -> Projector::ProjectedPredicate { + Projector::project_predicate(NumericPredicateBox::LessThan(expected)) + } + + /// Creates a predicate that checks if the numeric value is less than or equal to the expected value. + pub fn le(&self, expected: Numeric) -> Projector::ProjectedPredicate { + Projector::project_predicate(NumericPredicateBox::LessThanOrEquals(expected)) + } + + /// Creates a predicate that checks if the numeric value is greater than the expected value. + pub fn gt(&self, expected: Numeric) -> Projector::ProjectedPredicate { + Projector::project_predicate(NumericPredicateBox::GreaterThan(expected)) + } + + /// Creates a predicate that checks if the numeric value is greater than or equal to the expected value. + pub fn ge(&self, expected: Numeric) -> Projector::ProjectedPredicate { + Projector::project_predicate(NumericPredicateBox::GreaterThanOrEquals(expected)) + } +} + /// A prototype of [`crate::metadata::Metadata`] for predicate construction. #[derive(Default, Copy, Clone)] pub struct MetadataPrototype { diff --git a/crates/iroha_data_model/src/visit.rs b/crates/iroha_data_model/src/visit.rs index 92b8709c618..a1fc684f560 100644 --- a/crates/iroha_data_model/src/visit.rs +++ b/crates/iroha_data_model/src/visit.rs @@ -57,7 +57,6 @@ pub trait Visit { visit_find_parameters(&FindParameters), visit_find_domain_metadata(&FindDomainMetadata), visit_find_account_metadata(&FindAccountMetadata), - visit_find_asset_metadata(&FindAssetMetadata), visit_find_asset_definition_metadata(&FindAssetDefinitionMetadata), visit_find_trigger_metadata(&FindTriggerMetadata), @@ -83,7 +82,6 @@ pub trait Visit { visit_register_domain(&Register), visit_register_account(&Register), visit_register_asset_definition(&Register), - visit_register_asset(&Register), visit_register_role(&Register), visit_register_trigger(&Register), @@ -92,7 +90,6 @@ pub trait Visit { visit_unregister_domain(&Unregister), visit_unregister_account(&Unregister), visit_unregister_asset_definition(&Unregister), - visit_unregister_asset(&Unregister), // TODO: Need to allow role creator to unregister it somehow visit_unregister_role(&Unregister), visit_unregister_trigger(&Unregister), @@ -108,21 +105,18 @@ pub trait Visit { // Visit TransferBox visit_transfer_asset_definition(&Transfer), visit_transfer_asset_numeric(&Transfer), - visit_transfer_asset_store(&Transfer), visit_transfer_domain(&Transfer), // Visit SetKeyValueBox visit_set_domain_key_value(&SetKeyValue), visit_set_account_key_value(&SetKeyValue), visit_set_asset_definition_key_value(&SetKeyValue), - visit_set_asset_key_value(&SetKeyValue), visit_set_trigger_key_value(&SetKeyValue), // Visit RemoveKeyValueBox visit_remove_domain_key_value(&RemoveKeyValue), visit_remove_account_key_value(&RemoveKeyValue), visit_remove_asset_definition_key_value(&RemoveKeyValue), - visit_remove_asset_key_value(&RemoveKeyValue), visit_remove_trigger_key_value(&RemoveKeyValue), // Visit GrantBox @@ -163,7 +157,6 @@ pub fn visit_singular_query(visitor: &mut V, query: &Singular visit_find_parameters(FindParameters), visit_find_domain_metadata(FindDomainMetadata), visit_find_account_metadata(FindAccountMetadata), - visit_find_asset_metadata(FindAssetMetadata), visit_find_asset_definition_metadata(FindAssetDefinitionMetadata), visit_find_trigger_metadata(FindTriggerMetadata), } @@ -240,7 +233,6 @@ pub fn visit_register(visitor: &mut V, isi: &RegisterBox) { RegisterBox::Domain(obj) => visitor.visit_register_domain(obj), RegisterBox::Account(obj) => visitor.visit_register_account(obj), RegisterBox::AssetDefinition(obj) => visitor.visit_register_asset_definition(obj), - RegisterBox::Asset(obj) => visitor.visit_register_asset(obj), RegisterBox::Role(obj) => visitor.visit_register_role(obj), RegisterBox::Trigger(obj) => visitor.visit_register_trigger(obj), } @@ -252,7 +244,6 @@ pub fn visit_unregister(visitor: &mut V, isi: &UnregisterBox) UnregisterBox::Domain(obj) => visitor.visit_unregister_domain(obj), UnregisterBox::Account(obj) => visitor.visit_unregister_account(obj), UnregisterBox::AssetDefinition(obj) => visitor.visit_unregister_asset_definition(obj), - UnregisterBox::Asset(obj) => visitor.visit_unregister_asset(obj), UnregisterBox::Role(obj) => visitor.visit_unregister_role(obj), UnregisterBox::Trigger(obj) => visitor.visit_unregister_trigger(obj), } @@ -276,10 +267,7 @@ pub fn visit_transfer(visitor: &mut V, isi: &TransferBox) { match isi { TransferBox::Domain(obj) => visitor.visit_transfer_domain(obj), TransferBox::AssetDefinition(obj) => visitor.visit_transfer_asset_definition(obj), - TransferBox::Asset(transfer_asset) => match transfer_asset { - AssetTransferBox::Numeric(obj) => visitor.visit_transfer_asset_numeric(obj), - AssetTransferBox::Store(obj) => visitor.visit_transfer_asset_store(obj), - }, + TransferBox::Numeric(obj) => visitor.visit_transfer_asset_numeric(obj), } } @@ -288,7 +276,6 @@ pub fn visit_set_key_value(visitor: &mut V, isi: &SetKeyValue SetKeyValueBox::Domain(obj) => visitor.visit_set_domain_key_value(obj), SetKeyValueBox::Account(obj) => visitor.visit_set_account_key_value(obj), SetKeyValueBox::AssetDefinition(obj) => visitor.visit_set_asset_definition_key_value(obj), - SetKeyValueBox::Asset(obj) => visitor.visit_set_asset_key_value(obj), SetKeyValueBox::Trigger(obj) => visitor.visit_set_trigger_key_value(obj), } } @@ -300,7 +287,6 @@ pub fn visit_remove_key_value(visitor: &mut V, isi: &RemoveKe RemoveKeyValueBox::AssetDefinition(obj) => { visitor.visit_remove_asset_definition_key_value(obj) } - RemoveKeyValueBox::Asset(obj) => visitor.visit_remove_asset_key_value(obj), RemoveKeyValueBox::Trigger(obj) => visitor.visit_remove_trigger_key_value(obj), } } @@ -335,14 +321,9 @@ leaf_visitors! { visit_unregister_account(&Unregister), visit_set_account_key_value(&SetKeyValue), visit_remove_account_key_value(&RemoveKeyValue), - visit_register_asset(&Register), - visit_unregister_asset(&Unregister), visit_mint_asset_numeric(&Mint), visit_burn_asset_numeric(&Burn), visit_transfer_asset_numeric(&Transfer), - visit_transfer_asset_store(&Transfer), - visit_set_asset_key_value(&SetKeyValue), - visit_remove_asset_key_value(&RemoveKeyValue), visit_set_trigger_key_value(&SetKeyValue), visit_remove_trigger_key_value(&RemoveKeyValue), visit_register_asset_definition(&Register), @@ -381,7 +362,6 @@ leaf_visitors! { visit_find_parameters(&FindParameters), visit_find_domain_metadata(&FindDomainMetadata), visit_find_account_metadata(&FindAccountMetadata), - visit_find_asset_metadata(&FindAssetMetadata), visit_find_asset_definition_metadata(&FindAssetDefinitionMetadata), visit_find_trigger_metadata(&FindTriggerMetadata), diff --git a/crates/iroha_executor/src/default.rs b/crates/iroha_executor/src/default.rs index 3b6382666af..f7ae5a713d8 100644 --- a/crates/iroha_executor/src/default.rs +++ b/crates/iroha_executor/src/default.rs @@ -7,11 +7,7 @@ pub use account::{ visit_register_account, visit_remove_account_key_value, visit_set_account_key_value, visit_unregister_account, }; -pub use asset::{ - visit_burn_asset_numeric, visit_mint_asset_numeric, visit_register_asset, - visit_remove_asset_key_value, visit_set_asset_key_value, visit_transfer_asset_numeric, - visit_transfer_asset_store, visit_unregister_asset, -}; +pub use asset::{visit_burn_asset_numeric, visit_mint_asset_numeric, visit_transfer_asset_numeric}; pub use asset_definition::{ visit_register_asset_definition, visit_remove_asset_definition_key_value, visit_set_asset_definition_key_value, visit_transfer_asset_definition, @@ -323,12 +319,6 @@ pub mod domain { AnyPermission::CanModifyAssetDefinitionMetadata(permission) => { permission.asset_definition.domain() == domain_id } - AnyPermission::CanRegisterAssetWithDefinition(permission) => { - permission.asset_definition.domain() == domain_id - } - AnyPermission::CanUnregisterAssetWithDefinition(permission) => { - permission.asset_definition.domain() == domain_id - } AnyPermission::CanMintAssetWithDefinition(permission) => { permission.asset_definition.domain() == domain_id } @@ -338,15 +328,6 @@ pub mod domain { AnyPermission::CanTransferAssetWithDefinition(permission) => { permission.asset_definition.domain() == domain_id } - AnyPermission::CanRegisterAsset(permission) => permission.owner.domain() == domain_id, - AnyPermission::CanUnregisterAsset(permission) => { - permission.asset.definition().domain() == domain_id - || permission.asset.account().domain() == domain_id - } - AnyPermission::CanModifyAssetMetadata(permission) => { - permission.asset.definition().domain() == domain_id - || permission.asset.account().domain() == domain_id - } AnyPermission::CanMintAsset(permission) => { permission.asset.definition().domain() == domain_id || permission.asset.account().domain() == domain_id @@ -535,13 +516,6 @@ pub mod account { AnyPermission::CanModifyAccountMetadata(permission) => { permission.account == *account_id } - AnyPermission::CanRegisterAsset(permission) => permission.owner == *account_id, - AnyPermission::CanUnregisterAsset(permission) => { - permission.asset.account() == account_id - } - AnyPermission::CanModifyAssetMetadata(permission) => { - permission.asset.account() == account_id - } AnyPermission::CanMintAsset(permission) => permission.asset.account() == account_id, AnyPermission::CanBurnAsset(permission) => permission.asset.account() == account_id, AnyPermission::CanTransferAsset(permission) => permission.asset.account() == account_id, @@ -558,8 +532,6 @@ pub mod account { | AnyPermission::CanRegisterAssetDefinition(_) | AnyPermission::CanUnregisterAssetDefinition(_) | AnyPermission::CanModifyAssetDefinitionMetadata(_) - | AnyPermission::CanRegisterAssetWithDefinition(_) - | AnyPermission::CanUnregisterAssetWithDefinition(_) | AnyPermission::CanMintAssetWithDefinition(_) | AnyPermission::CanBurnAssetWithDefinition(_) | AnyPermission::CanTransferAssetWithDefinition(_) @@ -779,12 +751,6 @@ pub mod asset_definition { AnyPermission::CanModifyAssetDefinitionMetadata(permission) => { &permission.asset_definition == asset_definition_id } - AnyPermission::CanRegisterAssetWithDefinition(permission) => { - &permission.asset_definition == asset_definition_id - } - AnyPermission::CanUnregisterAssetWithDefinition(permission) => { - &permission.asset_definition == asset_definition_id - } AnyPermission::CanMintAssetWithDefinition(permission) => { &permission.asset_definition == asset_definition_id } @@ -794,12 +760,6 @@ pub mod asset_definition { AnyPermission::CanTransferAssetWithDefinition(permission) => { &permission.asset_definition == asset_definition_id } - AnyPermission::CanUnregisterAsset(permission) => { - permission.asset.definition() == asset_definition_id - } - AnyPermission::CanModifyAssetMetadata(permission) => { - permission.asset.definition() == asset_definition_id - } AnyPermission::CanMintAsset(permission) => { permission.asset.definition() == asset_definition_id } @@ -810,7 +770,6 @@ pub mod asset_definition { permission.asset.definition() == asset_definition_id } AnyPermission::CanUnregisterAccount(_) - | AnyPermission::CanRegisterAsset(_) | AnyPermission::CanModifyAccountMetadata(_) | AnyPermission::CanRegisterTrigger(_) | AnyPermission::CanUnregisterTrigger(_) @@ -833,106 +792,16 @@ pub mod asset_definition { pub mod asset { use iroha_executor_data_model::permission::asset::{ CanBurnAsset, CanBurnAssetWithDefinition, CanMintAsset, CanMintAssetWithDefinition, - CanModifyAssetMetadata, CanRegisterAsset, CanRegisterAssetWithDefinition, CanTransferAsset, - CanTransferAssetWithDefinition, CanUnregisterAsset, CanUnregisterAssetWithDefinition, - }; - use iroha_smart_contract::data_model::{ - asset::AssetValue, isi::BuiltInInstruction, metadata::Metadata, + CanTransferAsset, CanTransferAssetWithDefinition, }; - use iroha_smart_contract_utils::Encode; use super::*; use crate::permission::{asset::is_asset_owner, asset_definition::is_asset_definition_owner}; - pub fn visit_register_asset( - executor: &mut V, - isi: &Register, - ) { - let asset = isi.object(); - - if is_genesis(executor) { - execute!(executor, isi); - } - match is_asset_definition_owner( - asset.id().definition(), - &executor.context().authority, - executor.host(), - ) { - Err(err) => deny!(executor, err), - Ok(true) => execute!(executor, isi), - Ok(false) => {} - } - let can_register_assets_with_definition_token = CanRegisterAssetWithDefinition { - asset_definition: asset.id().definition().clone(), - }; - if can_register_assets_with_definition_token - .is_owned_by(&executor.context().authority, executor.host()) - { - execute!(executor, isi); - } - let can_register_user_asset_token = CanRegisterAsset { - owner: asset.id().account().clone(), - }; - if can_register_user_asset_token.is_owned_by(&executor.context().authority, executor.host()) - { - execute!(executor, isi); - } - - deny!( - executor, - "Can't register assets with definitions registered by other accounts" - ); - } - - pub fn visit_unregister_asset( + pub fn visit_mint_asset_numeric( executor: &mut V, - isi: &Unregister, + isi: &Mint, ) { - let asset_id = isi.object(); - - if is_genesis(executor) { - execute!(executor, isi); - } - match is_asset_owner(asset_id, &executor.context().authority, executor.host()) { - Err(err) => deny!(executor, err), - Ok(true) => execute!(executor, isi), - Ok(false) => {} - } - match is_asset_definition_owner( - asset_id.definition(), - &executor.context().authority, - executor.host(), - ) { - Err(err) => deny!(executor, err), - Ok(true) => execute!(executor, isi), - Ok(false) => {} - } - let can_unregister_assets_with_definition_token = CanUnregisterAssetWithDefinition { - asset_definition: asset_id.definition().clone(), - }; - if can_unregister_assets_with_definition_token - .is_owned_by(&executor.context().authority, executor.host()) - { - execute!(executor, isi); - } - let can_unregister_user_asset_token = CanUnregisterAsset { - asset: asset_id.clone(), - }; - if can_unregister_user_asset_token - .is_owned_by(&executor.context().authority, executor.host()) - { - execute!(executor, isi); - } - - deny!(executor, "Can't unregister asset from another account"); - } - - fn execute_mint_asset(executor: &mut V, isi: &Mint) - where - V: Execute + Visit + ?Sized, - Q: Into, - Mint: BuiltInInstruction + Encode, - { let asset_id = isi.destination(); if is_genesis(executor) { execute!(executor, isi); @@ -967,19 +836,10 @@ pub mod asset { ); } - pub fn visit_mint_asset_numeric( + pub fn visit_burn_asset_numeric( executor: &mut V, - isi: &Mint, + isi: &Burn, ) { - execute_mint_asset(executor, isi); - } - - fn execute_burn_asset(executor: &mut V, isi: &Burn) - where - V: Execute + Visit + ?Sized, - Q: Into, - Burn: BuiltInInstruction + Encode, - { let asset_id = isi.destination(); if is_genesis(executor) { execute!(executor, isi); @@ -1016,19 +876,10 @@ pub mod asset { deny!(executor, "Can't burn assets from another account"); } - pub fn visit_burn_asset_numeric( + pub fn visit_transfer_asset_numeric( executor: &mut V, - isi: &Burn, + isi: &Transfer, ) { - execute_burn_asset(executor, isi); - } - - fn execute_transfer_asset(executor: &mut V, isi: &Transfer) - where - V: Execute + Visit + ?Sized, - Q: Into, - Transfer: BuiltInInstruction + Encode, - { let asset_id = isi.source(); if is_genesis(executor) { execute!(executor, isi); @@ -1065,79 +916,6 @@ pub mod asset { deny!(executor, "Can't transfer assets of another account"); } - - pub fn visit_transfer_asset_numeric( - executor: &mut V, - isi: &Transfer, - ) { - execute_transfer_asset(executor, isi); - } - - pub fn visit_transfer_asset_store( - executor: &mut V, - isi: &Transfer, - ) { - execute_transfer_asset(executor, isi); - } - - pub fn visit_set_asset_key_value( - executor: &mut V, - isi: &SetKeyValue, - ) { - let asset_id = isi.object(); - - if is_genesis(executor) { - execute!(executor, isi); - } - match is_asset_owner(asset_id, &executor.context().authority, executor.host()) { - Err(err) => deny!(executor, err), - Ok(true) => execute!(executor, isi), - Ok(false) => {} - } - - let can_set_key_value_in_user_asset_token = CanModifyAssetMetadata { - asset: asset_id.clone(), - }; - if can_set_key_value_in_user_asset_token - .is_owned_by(&executor.context().authority, executor.host()) - { - execute!(executor, isi); - } - - deny!( - executor, - "Can't set value to the asset metadata of another account" - ); - } - - pub fn visit_remove_asset_key_value( - executor: &mut V, - isi: &RemoveKeyValue, - ) { - let asset_id = isi.object(); - - if is_genesis(executor) { - execute!(executor, isi); - } - match is_asset_owner(asset_id, &executor.context().authority, executor.host()) { - Err(err) => deny!(executor, err), - Ok(true) => execute!(executor, isi), - Ok(false) => {} - } - let can_remove_key_value_in_user_asset_token = CanModifyAssetMetadata { - asset: asset_id.clone(), - }; - if can_remove_key_value_in_user_asset_token - .is_owned_by(&executor.context().authority, executor.host()) - { - execute!(executor, isi); - } - - deny!( - executor, - "Can't remove value from the asset metadata of another account" - ); - } } pub mod parameter { @@ -1565,14 +1343,9 @@ pub mod trigger { | AnyPermission::CanModifyAccountMetadata(_) | AnyPermission::CanUnregisterAssetDefinition(_) | AnyPermission::CanModifyAssetDefinitionMetadata(_) - | AnyPermission::CanRegisterAssetWithDefinition(_) - | AnyPermission::CanUnregisterAssetWithDefinition(_) - | AnyPermission::CanRegisterAsset(_) - | AnyPermission::CanUnregisterAsset(_) | AnyPermission::CanMintAssetWithDefinition(_) | AnyPermission::CanBurnAssetWithDefinition(_) | AnyPermission::CanTransferAssetWithDefinition(_) - | AnyPermission::CanModifyAssetMetadata(_) | AnyPermission::CanMintAsset(_) | AnyPermission::CanBurnAsset(_) | AnyPermission::CanTransferAsset(_) diff --git a/crates/iroha_executor/src/permission.rs b/crates/iroha_executor/src/permission.rs index 570490af679..da626e7fabf 100644 --- a/crates/iroha_executor/src/permission.rs +++ b/crates/iroha_executor/src/permission.rs @@ -102,17 +102,12 @@ declare_permissions! { iroha_executor_data_model::permission::asset_definition::{CanUnregisterAssetDefinition}, iroha_executor_data_model::permission::asset_definition::{CanModifyAssetDefinitionMetadata}, - iroha_executor_data_model::permission::asset::{CanRegisterAssetWithDefinition}, - iroha_executor_data_model::permission::asset::{CanUnregisterAssetWithDefinition}, iroha_executor_data_model::permission::asset::{CanMintAssetWithDefinition}, iroha_executor_data_model::permission::asset::{CanBurnAssetWithDefinition}, iroha_executor_data_model::permission::asset::{CanTransferAssetWithDefinition}, - iroha_executor_data_model::permission::asset::{CanRegisterAsset}, - iroha_executor_data_model::permission::asset::{CanUnregisterAsset}, iroha_executor_data_model::permission::asset::{CanMintAsset}, iroha_executor_data_model::permission::asset::{CanBurnAsset}, iroha_executor_data_model::permission::asset::{CanTransferAsset}, - iroha_executor_data_model::permission::asset::{CanModifyAssetMetadata}, iroha_executor_data_model::permission::parameter::{CanSetParameters}, iroha_executor_data_model::permission::role::{CanManageRoles}, @@ -291,8 +286,7 @@ pub mod asset { use iroha_executor_data_model::permission::asset::{ CanBurnAsset, CanBurnAssetWithDefinition, CanMintAsset, CanMintAssetWithDefinition, - CanModifyAssetMetadata, CanRegisterAsset, CanRegisterAssetWithDefinition, CanTransferAsset, - CanTransferAssetWithDefinition, CanUnregisterAsset, CanUnregisterAssetWithDefinition, + CanTransferAsset, CanTransferAssetWithDefinition, }; use super::*; @@ -329,34 +323,6 @@ pub mod asset { } } - impl ValidateGrantRevoke for CanRegisterAssetWithDefinition { - fn validate_grant(&self, authority: &AccountId, context: &Context, host: &Iroha) -> Result { - super::asset_definition::Owner::from(self).validate(authority, host, context) - } - fn validate_revoke( - &self, - authority: &AccountId, - context: &Context, - host: &Iroha, - ) -> Result { - super::asset_definition::Owner::from(self).validate(authority, host, context) - } - } - - impl ValidateGrantRevoke for CanUnregisterAssetWithDefinition { - fn validate_grant(&self, authority: &AccountId, context: &Context, host: &Iroha) -> Result { - super::asset_definition::Owner::from(self).validate(authority, host, context) - } - fn validate_revoke( - &self, - authority: &AccountId, - context: &Context, - host: &Iroha, - ) -> Result { - super::asset_definition::Owner::from(self).validate(authority, host, context) - } - } - impl ValidateGrantRevoke for CanMintAssetWithDefinition { fn validate_grant(&self, authority: &AccountId, context: &Context, host: &Iroha) -> Result { super::asset_definition::Owner::from(self).validate(authority, host, context) @@ -399,34 +365,6 @@ pub mod asset { } } - impl ValidateGrantRevoke for CanRegisterAsset { - fn validate_grant(&self, authority: &AccountId, context: &Context, host: &Iroha) -> Result { - super::account::Owner::from(self).validate(authority, host, context) - } - fn validate_revoke( - &self, - authority: &AccountId, - context: &Context, - host: &Iroha, - ) -> Result { - super::account::Owner::from(self).validate(authority, host, context) - } - } - - impl ValidateGrantRevoke for CanUnregisterAsset { - fn validate_grant(&self, authority: &AccountId, context: &Context, host: &Iroha) -> Result { - Owner::from(self).validate(authority, host, context) - } - fn validate_revoke( - &self, - authority: &AccountId, - context: &Context, - host: &Iroha, - ) -> Result { - Owner::from(self).validate(authority, host, context) - } - } - impl ValidateGrantRevoke for CanMintAsset { fn validate_grant(&self, authority: &AccountId, context: &Context, host: &Iroha) -> Result { Owner::from(self).validate(authority, host, context) @@ -469,28 +407,6 @@ pub mod asset { } } - impl ValidateGrantRevoke for CanModifyAssetMetadata { - fn validate_grant(&self, authority: &AccountId, context: &Context, host: &Iroha) -> Result { - Owner::from(self).validate(authority, host, context) - } - fn validate_revoke( - &self, - authority: &AccountId, - context: &Context, - host: &Iroha, - ) -> Result { - Owner::from(self).validate(authority, host, context) - } - } - - impl<'t> From<&'t CanRegisterAsset> for super::account::Owner<'t> { - fn from(value: &'t CanRegisterAsset) -> Self { - Self { - account: &value.owner, - } - } - } - macro_rules! impl_froms { ($($name:ty),+ $(,)?) => {$( impl<'t> From<&'t $name> for Owner<'t> { @@ -501,13 +417,7 @@ pub mod asset { }; } - impl_froms!( - CanUnregisterAsset, - CanMintAsset, - CanBurnAsset, - CanTransferAsset, - CanModifyAssetMetadata, - ); + impl_froms!(CanMintAsset, CanBurnAsset, CanTransferAsset,); } pub mod asset_definition { @@ -639,8 +549,6 @@ pub mod asset_definition { impl_froms!( CanUnregisterAssetDefinition, CanModifyAssetDefinitionMetadata, - iroha_executor_data_model::permission::asset::CanRegisterAssetWithDefinition, - iroha_executor_data_model::permission::asset::CanUnregisterAssetWithDefinition, iroha_executor_data_model::permission::asset::CanMintAssetWithDefinition, iroha_executor_data_model::permission::asset::CanBurnAssetWithDefinition, iroha_executor_data_model::permission::asset::CanTransferAssetWithDefinition, diff --git a/crates/iroha_executor_data_model/src/permission.rs b/crates/iroha_executor_data_model/src/permission.rs index 27778496268..6074aec91b7 100644 --- a/crates/iroha_executor_data_model/src/permission.rs +++ b/crates/iroha_executor_data_model/src/permission.rs @@ -108,18 +108,6 @@ pub mod account { pub mod asset { use super::*; - permission! { - pub struct CanRegisterAssetWithDefinition { - pub asset_definition: AssetDefinitionId, - } - } - - permission! { - pub struct CanUnregisterAssetWithDefinition { - pub asset_definition: AssetDefinitionId, - } - } - permission! { pub struct CanMintAssetWithDefinition { pub asset_definition: AssetDefinitionId, @@ -138,18 +126,6 @@ pub mod asset { } } - permission! { - pub struct CanRegisterAsset { - pub owner: AccountId, - } - } - - permission! { - pub struct CanUnregisterAsset { - pub asset: AssetId, - } - } - permission! { pub struct CanMintAsset { pub asset: AssetId, @@ -167,12 +143,6 @@ pub mod asset { pub asset: AssetId, } } - - permission! { - pub struct CanModifyAssetMetadata { - pub asset: AssetId, - } - } } pub mod trigger { diff --git a/crates/iroha_executor_derive/src/default.rs b/crates/iroha_executor_derive/src/default.rs index c5def5c00b6..600c7f31043 100644 --- a/crates/iroha_executor_derive/src/default.rs +++ b/crates/iroha_executor_derive/src/default.rs @@ -124,14 +124,9 @@ pub fn impl_derive_visit(emitter: &mut Emitter, input: &syn::DeriveInput) -> Tok "fn visit_unregister_account(operation: &Unregister)", "fn visit_set_account_key_value(operation: &SetKeyValue)", "fn visit_remove_account_key_value(operation: &RemoveKeyValue)", - "fn visit_register_asset(operation: &Register)", - "fn visit_unregister_asset(operation: &Unregister)", "fn visit_mint_asset_numeric(operation: &Mint)", "fn visit_burn_asset_numeric(operation: &Burn)", "fn visit_transfer_asset_numeric(operation: &Transfer)", - "fn visit_transfer_asset_store(operation: &Transfer)", - "fn visit_set_asset_key_value(operation: &SetKeyValue)", - "fn visit_remove_asset_key_value(operation: &RemoveKeyValue)", "fn visit_set_trigger_key_value(operation: &SetKeyValue)", "fn visit_remove_trigger_key_value(operation: &RemoveKeyValue)", "fn visit_register_asset_definition(operation: &Register)", diff --git a/crates/iroha_genesis/src/lib.rs b/crates/iroha_genesis/src/lib.rs index 70649c91ebd..81cc3fef39a 100644 --- a/crates/iroha_genesis/src/lib.rs +++ b/crates/iroha_genesis/src/lib.rs @@ -319,9 +319,9 @@ impl GenesisDomainBuilder { } /// Add [`AssetDefinition`] to current domain. - pub fn asset(mut self, asset_name: Name, asset_type: AssetType) -> Self { + pub fn asset(mut self, asset_name: Name) -> Self { let asset_definition_id = AssetDefinitionId::new(self.domain_id.clone(), asset_name); - let asset_definition = AssetDefinition::new(asset_definition_id, asset_type); + let asset_definition = AssetDefinition::new(asset_definition_id); self.instructions .push(Register::asset_definition(asset_definition).into()); self @@ -404,10 +404,7 @@ mod tests { .finish_domain() .domain("meadow".parse().unwrap()) .account(public_key["mad_hatter"].clone()) - .asset( - "hats".parse().unwrap(), - AssetType::Numeric(NumericSpec::default()), - ) + .asset("hats".parse().unwrap()) .finish_domain(); // In real cases executor should be constructed from a wasm blob @@ -493,10 +490,8 @@ mod tests { ); assert_eq!( instructions[7], - Register::asset_definition(AssetDefinition::numeric( - "hats#meadow".parse().unwrap(), - )) - .into() + Register::asset_definition(AssetDefinition::new("hats#meadow".parse().unwrap())) + .into() ); } } diff --git a/crates/iroha_kagami/src/genesis/generate.rs b/crates/iroha_kagami/src/genesis/generate.rs index b0bc4601f88..ae41efa85c4 100644 --- a/crates/iroha_kagami/src/genesis/generate.rs +++ b/crates/iroha_kagami/src/genesis/generate.rs @@ -96,14 +96,11 @@ pub fn generate_default( .domain_with_metadata("wonderland".parse()?, meta.clone()) .account_with_metadata(ALICE_ID.signatory().clone(), meta.clone()) .account_with_metadata(BOB_ID.signatory().clone(), meta) - .asset("rose".parse()?, AssetType::Numeric(NumericSpec::default())) + .asset("rose".parse()?) .finish_domain() .domain("garden_of_live_flowers".parse()?) .account(CARPENTER_ID.signatory().clone()) - .asset( - "cabbage".parse()?, - AssetType::Numeric(NumericSpec::default()), - ) + .asset("cabbage".parse()?) .finish_domain(); let mint = Mint::asset_numeric( @@ -176,7 +173,6 @@ fn generate_synthetic( format!("asset_{asset}#{domain_id}").parse()?; genesis.append_instruction(Register::asset_definition(AssetDefinition::new( asset_definition_id, - AssetType::Numeric(NumericSpec::default()), ))); } diff --git a/crates/iroha_schema_gen/src/lib.rs b/crates/iroha_schema_gen/src/lib.rs index 1ac635ede44..189efb091e5 100644 --- a/crates/iroha_schema_gen/src/lib.rs +++ b/crates/iroha_schema_gen/src/lib.rs @@ -73,15 +73,10 @@ pub fn build_schemas() -> MetaMap { permission::asset_definition::CanRegisterAssetDefinition, permission::asset_definition::CanUnregisterAssetDefinition, permission::asset_definition::CanModifyAssetDefinitionMetadata, - permission::asset::CanRegisterAssetWithDefinition, - permission::asset::CanUnregisterAssetWithDefinition, permission::asset::CanTransferAssetWithDefinition, - permission::asset::CanRegisterAsset, - permission::asset::CanUnregisterAsset, permission::asset::CanMintAsset, permission::asset::CanBurnAsset, permission::asset::CanTransferAsset, - permission::asset::CanModifyAssetMetadata, permission::parameter::CanSetParameters, permission::role::CanManageRoles, permission::trigger::CanRegisterTrigger, @@ -126,10 +121,6 @@ types!( AssetId, AssetIdPredicateBox, AssetPredicateBox, - AssetTransferBox, - AssetType, - AssetValue, - AssetValuePredicateBox, BlockEvent, BlockEventFilter, BlockHashPredicateBox, @@ -232,7 +223,6 @@ types!( FindTransactions, FindTriggers, FindAssetDefinitionMetadata, - FindAssetMetadata, FindAssetQuantityById, FindDomainMetadata, FindError, @@ -287,7 +277,6 @@ types!( Metadata, MetadataChanged, MetadataChanged, - MetadataChanged, MetadataChanged, MetadataChanged, MetadataPredicateBox, @@ -296,7 +285,7 @@ types!( MintBox, Mint, Mint, - Mismatch, + Mismatch, Name, NewAccount, NewAssetDefinition, @@ -306,6 +295,7 @@ types!( NonZeroU64, Numeric, NumericSpec, + NumericPredicateBox, Option, Option, Option, @@ -350,7 +340,6 @@ types!( QueryResponse, QuerySignature, Register, - Register, Register, RegisterBox, Register, @@ -358,7 +347,6 @@ types!( Register, Register, RemoveKeyValue, - RemoveKeyValue, RemoveKeyValue, RemoveKeyValueBox, RemoveKeyValue, @@ -378,7 +366,6 @@ types!( RolePermissionChanged, RolePredicateBox, SetKeyValue, - SetKeyValue, SetKeyValue, SetKeyValueBox, SetKeyValue, @@ -428,7 +415,6 @@ types!( TransactionStatus, Transfer, Transfer, - Transfer, Transfer, TransferBox, Trigger, @@ -445,7 +431,6 @@ types!( TriggerNumberOfExecutionsChanged, TypeError, Unregister, - Unregister, Unregister, UnregisterBox, Unregister, @@ -605,21 +590,12 @@ mod tests { iroha_executor_data_model::permission::asset_definition::CanUnregisterAssetDefinition ); insert_into_test_map!(iroha_executor_data_model::permission::asset_definition::CanModifyAssetDefinitionMetadata); - insert_into_test_map!( - iroha_executor_data_model::permission::asset::CanRegisterAssetWithDefinition - ); - insert_into_test_map!( - iroha_executor_data_model::permission::asset::CanUnregisterAssetWithDefinition - ); insert_into_test_map!( iroha_executor_data_model::permission::asset::CanTransferAssetWithDefinition ); - insert_into_test_map!(iroha_executor_data_model::permission::asset::CanRegisterAsset); - insert_into_test_map!(iroha_executor_data_model::permission::asset::CanUnregisterAsset); insert_into_test_map!(iroha_executor_data_model::permission::asset::CanMintAsset); insert_into_test_map!(iroha_executor_data_model::permission::asset::CanBurnAsset); insert_into_test_map!(iroha_executor_data_model::permission::asset::CanTransferAsset); - insert_into_test_map!(iroha_executor_data_model::permission::asset::CanModifyAssetMetadata); insert_into_test_map!(iroha_executor_data_model::permission::parameter::CanSetParameters); insert_into_test_map!(iroha_executor_data_model::permission::role::CanManageRoles); insert_into_test_map!(iroha_executor_data_model::permission::trigger::CanRegisterTrigger); diff --git a/crates/iroha_smart_contract/src/lib.rs b/crates/iroha_smart_contract/src/lib.rs index 08131cde857..17b512b3be7 100644 --- a/crates/iroha_smart_contract/src/lib.rs +++ b/crates/iroha_smart_contract/src/lib.rs @@ -290,7 +290,7 @@ mod tests { fn get_test_instruction() -> InstructionBox { let new_asset_id: AssetId = "tulip##ed0120CE7FA46C9DCE7EA4B125E2E36BDB63EA33073E7590AC92816AE1E861B7048B03@wonderland".parse().unwrap(); - Register::asset(Asset::new(new_asset_id, 1_u32)).into() + Mint::asset_numeric(1_u32, new_asset_id).into() } fn get_test_query() -> FindAssetQuantityById { diff --git a/defaults/genesis.json b/defaults/genesis.json index ad3aff497fe..000beb59144 100644 --- a/defaults/genesis.json +++ b/defaults/genesis.json @@ -59,7 +59,7 @@ "Register": { "AssetDefinition": { "id": "rose#wonderland", - "type": "Numeric", + "spec": "Numeric", "mintable": "Infinitely", "logo": null, "metadata": {} @@ -87,7 +87,7 @@ "Register": { "AssetDefinition": { "id": "cabbage#garden_of_live_flowers", - "type": "Numeric", + "spec": "Numeric", "mintable": "Infinitely", "logo": null, "metadata": {} diff --git a/wasm_samples/Cargo.toml b/wasm_samples/Cargo.toml index 6ebcb8fb9e5..2efbd030179 100644 --- a/wasm_samples/Cargo.toml +++ b/wasm_samples/Cargo.toml @@ -10,7 +10,6 @@ license = "Apache-2.0" resolver = "2" members = [ "default_executor", - "create_nft_for_every_user_trigger", "mint_rose_trigger", "mint_rose_trigger_args", "executor_with_admin", diff --git a/wasm_samples/create_nft_for_every_user_trigger/Cargo.toml b/wasm_samples/create_nft_for_every_user_trigger/Cargo.toml deleted file mode 100644 index 58f3433a861..00000000000 --- a/wasm_samples/create_nft_for_every_user_trigger/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "create_nft_for_every_user_trigger" - -edition.workspace = true -version.workspace = true -authors.workspace = true - -license.workspace = true - -[lib] -crate-type = ['cdylib'] - -[dependencies] -iroha_trigger.workspace = true - -panic-halt.workspace = true -dlmalloc.workspace = true -getrandom.workspace = true diff --git a/wasm_samples/create_nft_for_every_user_trigger/src/lib.rs b/wasm_samples/create_nft_for_every_user_trigger/src/lib.rs deleted file mode 100644 index 415329d8a0f..00000000000 --- a/wasm_samples/create_nft_for_every_user_trigger/src/lib.rs +++ /dev/null @@ -1,83 +0,0 @@ -//! Smartcontract which creates new nft for every user -#![no_std] - -extern crate alloc; -#[cfg(not(test))] -extern crate panic_halt; - -use alloc::{format, string::ToString}; - -use dlmalloc::GlobalDlmalloc; -use iroha_trigger::prelude::*; - -#[global_allocator] -static ALLOC: GlobalDlmalloc = GlobalDlmalloc; - -getrandom::register_custom_getrandom!(iroha_trigger::stub_getrandom); - -#[iroha_trigger::main] -fn main(host: Iroha, _context: Context) { - iroha_trigger::log::info!("Executing trigger"); - let accounts_cursor = host.query(FindAccounts).execute().dbg_unwrap(); - - 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()) { - continue; - } - - let mut metadata = Metadata::default(); - let name = format!( - "nft_for_{}_in_{}", - account.id().signatory(), - account.id().domain() - ) - .parse() - .dbg_unwrap(); - metadata.insert(name, true); - - let nft_id = generate_new_nft_id(&host, account.id()); - let nft_definition = AssetDefinition::store(nft_id.clone()) - .mintable_once() - .with_metadata(metadata); - let account_nft_id = AssetId::new(nft_id, account.id().clone()); - let account_nft = Asset::new(account_nft_id, Metadata::default()); - - host.submit(&Register::asset_definition(nft_definition)) - .dbg_unwrap(); - host.submit(&Register::asset(account_nft)).dbg_unwrap(); - } - - iroha_trigger::log::info!("Smart contract executed successfully"); -} - -fn generate_new_nft_id(host: &Iroha, account_id: &AccountId) -> AssetDefinitionId { - let assets = host - .query(FindAssets) - .filter_with(|asset| asset.id.account.eq(account_id.clone())) - .execute() - .dbg_unwrap(); - - let new_number = assets - .map(|res| res.dbg_unwrap()) - .filter(|asset| asset.id().definition().to_string().starts_with("nft_")) - .count() - .checked_add(1) - .dbg_unwrap(); - iroha_trigger::log::debug!(&format!("New number: {}", new_number)); - - format!( - "nft_number_{}_for_{}#{}", - new_number, - account_id.signatory(), - account_id.domain() - ) - .parse() - .dbg_unwrap() -} diff --git a/wasm_samples/smart_contract_can_filter_queries/src/lib.rs b/wasm_samples/smart_contract_can_filter_queries/src/lib.rs index 2501f27fac0..ffad7d47be7 100644 --- a/wasm_samples/smart_contract_can_filter_queries/src/lib.rs +++ b/wasm_samples/smart_contract_can_filter_queries/src/lib.rs @@ -30,13 +30,11 @@ fn main(host: Iroha, _context: Context) { host.submit(&Register::asset_definition(AssetDefinition::new( time_id.clone(), - AssetType::Numeric(NumericSpec::default()), ))) .dbg_unwrap(); host.submit(&Register::asset_definition(AssetDefinition::new( space_id.clone(), - AssetType::Numeric(NumericSpec::default()), ))) .dbg_unwrap();