From 1d81e1db302f29543a146cd7b4d9e52eb20d5aa3 Mon Sep 17 00:00:00 2001 From: Aleksandr Petrosyan Date: Thu, 25 Aug 2022 14:14:21 +0400 Subject: [PATCH] [feature] #2085: Add `Address` Signed-off-by: Aleksandr Petrosyan --- cli/src/torii/mod.rs | 2 +- cli/src/torii/tests.rs | 20 +- client/benches/torii.rs | 10 +- client/benches/tps/lib.rs | 21 +- client/examples/million_accounts_genesis.rs | 12 +- client/src/client.rs | 7 +- client/src/lib.rs | 5 +- client/tests/integration/add_account.rs | 21 +- client/tests/integration/asset.rs | 48 +- client/tests/integration/asset_propagation.rs | 6 +- client/tests/integration/burn_public_keys.rs | 8 +- .../integration/multiple_blocks_created.rs | 23 +- .../integration/multisignature_account.rs | 4 +- .../integration/multisignature_transaction.rs | 7 +- client/tests/integration/non_mintable.rs | 12 +- client/tests/integration/offline_peers.rs | 11 +- client/tests/integration/permissions.rs | 106 ++-- client/tests/integration/queries/account.rs | 14 +- client/tests/integration/queries/role.rs | 2 +- client/tests/integration/query_errors.rs | 6 +- client/tests/integration/restart_peer.rs | 4 +- client/tests/integration/roles.rs | 28 +- client/tests/integration/sorting.rs | 52 +- client/tests/integration/transfer_asset.rs | 18 +- .../integration/triggers/by_call_trigger.rs | 14 +- .../integration/triggers/data_trigger.rs | 8 +- .../integration/triggers/event_trigger.rs | 6 +- .../integration/triggers/time_trigger.rs | 62 +- client/tests/integration/tx_history.rs | 6 +- client/tests/integration/tx_rollback.rs | 6 +- client/tests/integration/unregister_peer.rs | 5 +- client/tests/integration/unstable_network.rs | 9 +- client_cli/src/main.rs | 96 ++- config/src/client.rs | 8 +- core/benches/kura.rs | 14 +- core/benches/validation.rs | 10 +- core/src/genesis.rs | 183 +++--- core/src/queue.rs | 32 +- core/src/smartcontracts/isi/account.rs | 11 +- core/src/smartcontracts/isi/asset.rs | 12 +- core/src/smartcontracts/isi/domain.rs | 36 +- core/src/smartcontracts/isi/mod.rs | 54 +- .../src/smartcontracts/isi/permissions/mod.rs | 114 ++-- core/src/smartcontracts/isi/query.rs | 17 +- core/src/smartcontracts/wasm.rs | 77 +-- core/src/tx.rs | 12 +- core/src/wsv.rs | 4 +- core/test_network/src/lib.rs | 74 ++- data_model/src/account.rs | 202 +++++-- data_model/src/asset.rs | 13 +- data_model/src/block_value.rs | 74 ++- data_model/src/domain.rs | 184 +----- data_model/src/events/data/events.rs | 18 +- data_model/src/events/data/filters.rs | 6 +- data_model/src/expression.rs | 236 ++++---- data_model/src/ipfs.rs | 184 ++++++ data_model/src/isi.rs | 4 +- data_model/src/lib.rs | 236 +------- data_model/src/metadata.rs | 2 +- data_model/src/peer.rs | 2 +- data_model/src/permissions.rs | 2 +- data_model/src/predicate.rs | 24 +- data_model/src/query.rs | 52 +- data_model/src/trigger/mod.rs | 10 +- data_model/src/value.rs | 145 +++++ data_model/tests/data_model.rs | 11 +- .../src/private_blockchain/query.rs | 556 +++++++++--------- .../src/private_blockchain/tests/mod.rs | 28 +- .../tests/revoke_and_grant.rs | 37 +- .../src/public_blockchain/mod.rs | 307 +++++++--- tools/kagami/src/main.rs | 47 +- tools/parity_scale_decoder/Cargo.toml | 1 + tools/parity_scale_decoder/build.rs | 11 +- .../parity_scale_decoder/samples/account.bin | Bin 80 -> 111 bytes .../parity_scale_decoder/samples/account.json | 43 +- .../parity_scale_decoder/samples/trigger.bin | Bin 79 -> 163 bytes .../parity_scale_decoder/samples/trigger.json | 104 ++-- tools/parity_scale_decoder/src/main.rs | 8 +- 78 files changed, 2251 insertions(+), 1613 deletions(-) create mode 100644 data_model/src/ipfs.rs create mode 100644 data_model/src/value.rs diff --git a/cli/src/torii/mod.rs b/cli/src/torii/mod.rs index 2cc924c3915..9d221793809 100644 --- a/cli/src/torii/mod.rs +++ b/cli/src/torii/mod.rs @@ -89,7 +89,7 @@ pub enum Error { pub(crate) const fn query_status_code(query_error: &query::Error) -> StatusCode { use query::Error::*; match query_error { - Decode(_) | Evaluate(_) | Conversion(_) => StatusCode::BAD_REQUEST, + BareAccount | Decode(_) | Evaluate(_) | Conversion(_) => StatusCode::BAD_REQUEST, Signature(_) | Unauthorized => StatusCode::UNAUTHORIZED, Permission(_) => StatusCode::FORBIDDEN, Find(_) => StatusCode::NOT_FOUND, diff --git a/cli/src/torii/tests.rs b/cli/src/torii/tests.rs index e320df4b42f..5bbd3fdb121 100644 --- a/cli/src/torii/tests.rs +++ b/cli/src/torii/tests.rs @@ -18,9 +18,9 @@ use iroha_core::{ tx::TransactionValidator, wsv::World, }; -use iroha_data_model::{account::GENESIS_ACCOUNT_NAME, predicate::PredicateBox, prelude::*}; +use iroha_data_model::{account::genesis::GENESIS_ACCOUNT_NAME, predicate::PredicateBox, prelude::*}; use iroha_version::prelude::*; -use test_network::{prepare_test_for_nextest, unique_port}; +use test_network::*; use tokio::time; use warp::test::WsClient; @@ -35,7 +35,7 @@ async fn create_torii() -> (Torii, KeyPair) { config.torii.p2p_addr = format!("127.0.0.1:{}", unique_port::get_unique_free_port().unwrap()); config.torii.api_url = format!("127.0.0.1:{}", unique_port::get_unique_free_port().unwrap()); config.torii.telemetry_url = - format!("127.0.0.1:{}", unique_port::get_unique_free_port().unwrap()); + format!("127.0.0.1:{}", unique_port::get_unique_free_port().expect("Valid")); let (events, _) = tokio::sync::broadcast::channel(100); let wsv = Arc::new(WorldStateView::new(World::with( ('a'..='z') @@ -49,7 +49,7 @@ async fn create_torii() -> (Torii, KeyPair) { assert!(domain .add_account( Account::new( - AccountId::from_str("alice@wonderland").expect("Valid"), + Alias::from_str("alice@wonderland").expect("Valid"), [keys.public_key().clone()], ) .build() @@ -100,7 +100,7 @@ async fn torii_pagination() { let get_domains = |start, limit| { let query: VerifiedQueryRequest = QueryRequest::new( QueryBox::FindAllDomains(Default::default()), - AccountId::from_str("alice@wonderland").expect("Valid"), + Alias::from_str("alice@wonderland").expect("Valid").alice_key(), PredicateBox::default(), ) .sign(keys.clone()) @@ -185,7 +185,7 @@ impl QuerySet { torii.query_judge = Arc::new(DenyAll::new()); } - let authority = AccountId::from_str("alice@wonderland").expect("Valid"); + let authority = Alias::from_str("alice@wonderland").expect("Valid").alice_key(); for instruction in self.instructions { instruction .execute(authority.clone(), &torii.wsv) @@ -199,9 +199,9 @@ impl QuerySet { self.account.unwrap_or(authority), PredicateBox::default(), ) - .sign(self.keys.unwrap_or(keys)) - .expect("Failed to sign query with keys") - .into(); + .sign(self.keys.unwrap_or(keys)) + .expect("Failed to sign query with keys") + .into(); let response = warp::test::request() .method("POST") @@ -289,7 +289,7 @@ fn register_domain() -> Instruction { fn register_account(name: &str) -> Instruction { let (public_key, _) = KeyPair::generate().unwrap().into(); RegisterBox::new(Account::new( - AccountId::new(name.parse().expect("Valid"), DOMAIN.parse().expect("Valid")), + Alias::new(name.parse().expect("Valid"), DOMAIN.parse().expect("Valid")), [public_key], )) .into() diff --git a/client/benches/torii.rs b/client/benches/torii.rs index 9994de6d31d..f7cdf7264ff 100644 --- a/client/benches/torii.rs +++ b/client/benches/torii.rs @@ -51,11 +51,12 @@ fn query_requests(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("query-requests"); let domain_id: DomainId = "domain".parse().expect("Valid"); let create_domain = RegisterBox::new(Domain::new(domain_id.clone())); - let account_id = AccountId::new("account".parse().expect("Valid"), domain_id.clone()); let (public_key, _) = KeyPair::generate() .expect("Failed to generate KeyPair") .into(); - let create_account = RegisterBox::new(Account::new(account_id.clone(), [public_key])); + let account_alias = Alias::new("account".parse().expect("Valid"), domain_id.clone()); + let account_id = AccountId::new(public_key.clone(), account_alias); + let create_account = RegisterBox::new(Account::from_id(account_id.clone())); let asset_definition_id = AssetDefinitionId::new("xor".parse().expect("Valid"), domain_id); let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); let quantity: u32 = 200; @@ -143,11 +144,12 @@ fn instruction_submits(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("instruction-requests"); let domain_id: DomainId = "domain".parse().expect("Valid"); let create_domain = RegisterBox::new(Domain::new(domain_id.clone())); - let account_id = AccountId::new("account".parse().expect("Valid"), domain_id.clone()); + let alias = Alias::new("account".parse().expect("Valid"), domain_id.clone()); let (public_key, _) = KeyPair::generate() .expect("Failed to generate Key-pair.") .into(); - let create_account = RegisterBox::new(Account::new(account_id.clone(), [public_key])); + let account_id = AccountId::new(public_key.clone(), alias); + let create_account = RegisterBox::new(Account::from_id(account_id.clone())); let asset_definition_id = AssetDefinitionId::new("xor".parse().expect("Valid"), domain_id); let mut client_config = iroha_client::samples::get_client_config(&get_key_pair()); client_config.torii_api_url = SmallStr::from_string(peer.api_address.clone()); diff --git a/client/benches/tps/lib.rs b/client/benches/tps/lib.rs index 8d687c07975..3e99169bbd6 100644 --- a/client/benches/tps/lib.rs +++ b/client/benches/tps/lib.rs @@ -7,6 +7,7 @@ use std::{fmt, fs::File, io::BufReader, path::Path, str::FromStr as _, sync::mps use eyre::{Result, WrapErr}; use iroha_client::client::Client; +use iroha_crypto::KeyPair; use iroha_data_model::prelude::*; use iroha_permissions_validators::public_blockchain::{ burn::CanBurnUserAssets, transfer::CanTransferUserAssets, @@ -139,13 +140,19 @@ impl MeasurerUnit { let keypair = iroha_core::prelude::KeyPair::generate().expect("Failed to generate KeyPair."); - let account_id = account_id(self.name); - let alice_id = ::Id::from_str("alice@wonderland")?; + let account_id = { + let alias = account_id(self.name); + AccountId::new(keypair.public_key().clone(), alias) + }; + let alice_id = { + let alias = Alias::from_str("alice@wonderland")?; + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let asset_id = asset_id(self.name); - let register_me = RegisterBox::new(Account::new( - account_id.clone(), - [keypair.public_key().clone()], + let register_me = RegisterBox::new(Account::from_id( + account_id.clone() , )); self.client.submit_blocking(register_me)?; @@ -241,11 +248,11 @@ impl MeasurerUnit { fn asset_id(account_name: UnitName) -> AssetId { AssetId::new( "rose#wonderland".parse().expect("Valid"), - account_id(account_name), + account_id(account_name).fresh_key(), ) } #[allow(clippy::expect_used)] -fn account_id(name: UnitName) -> AccountId { +fn account_id(name: UnitName) -> Alias { format!("{}@wonderland", name).parse().expect("Valid") } diff --git a/client/examples/million_accounts_genesis.rs b/client/examples/million_accounts_genesis.rs index 4bfb415fb1b..98d7b73a056 100644 --- a/client/examples/million_accounts_genesis.rs +++ b/client/examples/million_accounts_genesis.rs @@ -6,6 +6,7 @@ use iroha::samples::get_config; use iroha_core::genesis::{ GenesisNetwork, GenesisNetworkTrait, RawGenesisBlock, RawGenesisBlockBuilder, }; +use iroha_crypto::KeyPair; use iroha_data_model::prelude::*; use test_network::{ get_key_pair, wait_for_genesis_committed, Peer as TestPeer, PeerBuilder, TestRuntime, @@ -65,12 +66,13 @@ fn create_million_accounts_directly() { wait_for_genesis_committed(&vec![test_client.clone()], 0); for i in 0_u32..1_000_000_u32 { let domain_id: DomainId = format!("wonderland-{}", i).parse().expect("Valid"); - let normal_account_id = AccountId::new( - format!("bob-{}", i).parse().expect("Valid"), - domain_id.clone(), - ); + let normal_account_id = { + let alias = Alias::new(format!("bob-{}", i).parse().expect("Valid"), domain_id.clone()); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let create_domain = RegisterBox::new(Domain::new(domain_id)); - let create_account = RegisterBox::new(Account::new(normal_account_id.clone(), [])); + let create_account = RegisterBox::new(Account::from_id(normal_account_id.clone())); if test_client .submit_all([create_domain.into(), create_account.into()].to_vec()) .is_err() diff --git a/client/src/client.rs b/client/src/client.rs index 22fe96af4f9..43ad7e616a8 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1161,11 +1161,16 @@ pub mod account { FindAllAccounts::new() } - /// Construct a query to get account by id + /// Construct a query to get account by id. The alias is ignored. pub fn by_id(account_id: impl Into>) -> FindAccountById { FindAccountById::new(account_id) } + /// Construct a query to get account by alias. + pub fn by_alias(alias: impl Into>) -> FindAccountIdByAlias { + FindAccountIdByAlias::new(alias) + } + /// Construct a query to get all accounts containing specified asset pub fn all_with_asset( asset_definition_id: impl Into>, diff --git a/client/src/lib.rs b/client/src/lib.rs index c0a5c21df25..fd3c08ecdbb 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -11,6 +11,7 @@ mod http_default; /// Module containing sample configurations for tests and benchmarks. pub mod samples { use iroha_config::torii::uri; + use iroha_core::tx::AccountId; use iroha_crypto::KeyPair; use super::Configuration; @@ -20,9 +21,9 @@ pub mod samples { pub fn get_client_config(key_pair: &KeyPair) -> Configuration { let (public_key, private_key) = key_pair.clone().into(); Configuration { - public_key, + public_key: public_key.clone(), private_key, - account_id: "alice@wonderland".parse().expect("Should not fail."), + account_id: AccountId::new(public_key, "alice@wonderland".parse().expect("Should not fail.")), torii_api_url: iroha_primitives::small::SmallStr::from_str(uri::DEFAULT_API_URL), ..Configuration::default() } diff --git a/client/tests/integration/add_account.rs b/client/tests/integration/add_account.rs index 3c922b78037..dd5f04c650f 100644 --- a/client/tests/integration/add_account.rs +++ b/client/tests/integration/add_account.rs @@ -16,25 +16,26 @@ fn client_add_account_with_name_length_more_than_limit_should_not_commit_transac let pipeline_time = super::Configuration::pipeline_time(); - let normal_account_id: AccountId = "bob@wonderland".parse().expect("Valid"); - let create_account = RegisterBox::new(Account::new(normal_account_id.clone(), [])); + let normal_account_id = "bob@wonderland".parse::().expect("Valid").fresh_key(); + let create_account = RegisterBox::new(Account::from_id(normal_account_id.clone())); test_client.submit(create_account)?; let too_long_account_name = "0".repeat(2_usize.pow(14)); - let incorrect_account_id: AccountId = (too_long_account_name + "@wonderland") - .parse() - .expect("Valid"); - let create_account = RegisterBox::new(Account::new(incorrect_account_id.clone(), [])); + let incorrect_account_id = (too_long_account_name + "@wonderland") + .parse::() + .expect("Valid") + .fresh_key(); + let create_account = RegisterBox::new(Account::from_id(incorrect_account_id.clone())); test_client.submit(create_account)?; thread::sleep(pipeline_time * 2); assert!(test_client - .request(client::account::by_id(normal_account_id)) - .is_ok()); + .request(client::account::by_id(normal_account_id)) + .is_ok()); assert!(test_client - .request(client::account::by_id(incorrect_account_id)) - .is_err()); + .request(client::account::by_id(incorrect_account_id)) + .is_err()); Ok(()) } diff --git a/client/tests/integration/asset.rs b/client/tests/integration/asset.rs index 49be2e93214..002b7fdc7d5 100644 --- a/client/tests/integration/asset.rs +++ b/client/tests/integration/asset.rs @@ -16,7 +16,7 @@ fn client_register_asset_should_add_asset_once_but_not_twice() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); // Given - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); + let account_id = Alias::from_str("alice@wonderland").expect("Valid").alice_key(); let asset_definition_id = AssetDefinitionId::from_str("test_asset#wonderland").expect("Valid"); let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); @@ -48,7 +48,7 @@ fn unregister_asset_should_remove_asset_from_account() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); // Given - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); + let account_id = Alias::from_str("alice@wonderland").expect("Valid").alice_key(); let asset_definition_id = AssetDefinitionId::from_str("test_asset#wonderland").expect("Valid"); let asset_id = AssetId::new(asset_definition_id.clone(), account_id.clone()); @@ -84,7 +84,7 @@ fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount() -> wait_for_genesis_committed(&vec![test_client.clone()], 0); // Given - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); + let account_id = Alias::from_str("alice@wonderland").expect("Valid").alice_key(); let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); let metadata = iroha_data_model::metadata::UnlimitedMetadata::default(); @@ -116,7 +116,7 @@ fn client_add_big_asset_quantity_to_existing_asset_should_increase_asset_amount( wait_for_genesis_committed(&vec![test_client.clone()], 0); // Given - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); + let account_id = Alias::from_str("alice@wonderland").expect("Valid").alice_key(); let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); let create_asset = RegisterBox::new(AssetDefinition::big_quantity(asset_definition_id.clone())); let metadata = iroha_data_model::metadata::UnlimitedMetadata::default(); @@ -147,7 +147,7 @@ fn client_add_asset_with_decimal_should_increase_asset_amount() -> Result<()> { let (_rt, _peer, mut test_client) = ::new().start_with_runtime(); // Given - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); + let account_id = Alias::from_str("alice@wonderland").expect("Valid").alice_key(); let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); let identifiable_box = AssetDefinition::fixed(asset_definition_id.clone()); let create_asset = RegisterBox::new(identifiable_box); @@ -164,25 +164,25 @@ fn client_add_asset_with_decimal_should_increase_asset_amount() -> Result<()> { ); let instructions: Vec = vec![create_asset.into(), mint.into()]; let tx = test_client.build_transaction(instructions.into(), metadata)?; - test_client.submit_transaction(tx)?; - test_client.poll_request(client::asset::by_account_id(account_id.clone()), |result| { - result.iter().any(|asset| { - asset.id().definition_id == asset_definition_id - && *asset.value() == AssetValue::Fixed(quantity) - }) - })?; - - // Add some fractional part - let quantity2: Fixed = Fixed::try_from(0.55_f64).unwrap(); - let mint = MintBox::new( - Value::Fixed(quantity2), - IdBox::AssetId(AssetId::new( - asset_definition_id.clone(), - account_id.clone(), - )), - ); - // and check that it is added without errors - let sum = quantity +test_client.submit_transaction(tx)?; +test_client.poll_request(client::asset::by_account_id(account_id.clone()), |result| { + result.iter().any(|asset| { + asset.id().definition_id == asset_definition_id + && *asset.value() == AssetValue::Fixed(quantity) + }) +})?; + +// Add some fractional part +let quantity2: Fixed = Fixed::try_from(0.55_f64).unwrap(); +let mint = MintBox::new( + Value::Fixed(quantity2), + IdBox::AssetId(AssetId::new( + asset_definition_id.clone(), + account_id.clone(), + )), +); +// and check that it is added without errors +let sum = quantity .checked_add(quantity2) .map_err(|e| eyre::eyre!("{}", e))?; test_client.submit_till(mint, client::asset::by_account_id(account_id), |result| { diff --git a/client/tests/integration/asset_propagation.rs b/client/tests/integration/asset_propagation.rs index e9baa5b46fe..0bcfd45dc32 100644 --- a/client/tests/integration/asset_propagation.rs +++ b/client/tests/integration/asset_propagation.rs @@ -4,7 +4,6 @@ use std::{str::FromStr as _, thread}; use eyre::Result; use iroha_client::client; -use iroha_core::prelude::*; use iroha_data_model::prelude::*; use test_network::*; @@ -20,9 +19,8 @@ fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount_on_a let pipeline_time = Configuration::pipeline_time(); let create_domain = RegisterBox::new(Domain::new(DomainId::from_str("domain")?)); - let account_id = AccountId::from_str("account@domain")?; - let (public_key, _) = KeyPair::generate()?.into(); - let create_account = RegisterBox::new(Account::new(account_id.clone(), [public_key])); + let account_id = Alias::from_str("account@domain")?.fresh_key(); + let create_account = RegisterBox::new(Account::from_id(account_id.clone())); let asset_definition_id = AssetDefinitionId::from_str("xor#domain")?; let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); iroha_client.submit_all(vec![ diff --git a/client/tests/integration/burn_public_keys.rs b/client/tests/integration/burn_public_keys.rs index 3856b238949..52392fe944f 100644 --- a/client/tests/integration/burn_public_keys.rs +++ b/client/tests/integration/burn_public_keys.rs @@ -6,6 +6,7 @@ use iroha_client::client::{account, transaction, Client}; use iroha_core::prelude::*; use iroha_data_model::prelude::*; use test_network::*; +use eyre::Result; use super::Configuration; @@ -26,16 +27,16 @@ fn account_keys_count(client: &mut Client, account_id: AccountId) -> usize { } #[test] -fn public_keys_cannot_be_burned_to_nothing() { +fn public_keys_cannot_be_burned_to_nothing() -> Result<()> { prepare_test_for_nextest!(); const KEYS_COUNT: usize = 3; - let bob_id: AccountId = "bob@wonderland".parse().expect("Valid"); + let bob_id = "bob@wonderland".parse::()?.fresh_key(); let bob_keys_count = |client: &mut Client| account_keys_count(client, bob_id.clone()); let (_rt, _peer, mut client) = ::new().start_with_runtime(); wait_for_genesis_committed(&vec![client.clone()], 0); - let register_bob = RegisterBox::new(Account::new(bob_id.clone(), [])).into(); + let register_bob = RegisterBox::new(Account::from_id(bob_id.clone())).into(); let _ = submit_and_get(&mut client, [register_bob]); let mut keys_count = bob_keys_count(&mut client); @@ -69,4 +70,5 @@ fn public_keys_cannot_be_burned_to_nothing() { committed_txn, TransactionValue::RejectedTransaction(_) )); + Ok(()) } diff --git a/client/tests/integration/multiple_blocks_created.rs b/client/tests/integration/multiple_blocks_created.rs index 21a5a6025b6..3af53874b9b 100644 --- a/client/tests/integration/multiple_blocks_created.rs +++ b/client/tests/integration/multiple_blocks_created.rs @@ -3,29 +3,26 @@ use std::thread; use iroha_client::client::{self, Client}; -use iroha_core::prelude::*; use iroha_data_model::prelude::*; use test_network::*; use super::Configuration; + const N_BLOCKS: usize = 510; #[ignore = "Takes a lot of time."] #[test] -fn long_multiple_blocks_created() { +fn long_multiple_blocks_created() -> eyre::Result<()> { // Given let (_rt, network, iroha_client) = ::start_test_with_runtime(4, 1); wait_for_genesis_committed(&network.clients(), 0); let pipeline_time = Configuration::pipeline_time(); let create_domain = RegisterBox::new(Domain::new("domain".parse().expect("Valid"))); - let account_id: AccountId = "account@domain".parse().expect("Valid"); - let (public_key, _) = KeyPair::generate() - .expect("Failed to generate KeyPair") - .into(); - let create_account = RegisterBox::new(Account::new(account_id.clone(), [public_key])); - let asset_definition_id: AssetDefinitionId = "xor#domain".parse().expect("Valid"); + let account_id = "account@domain".parse::()?.fresh_key(); + let create_account = RegisterBox::new(Account::from_id(account_id.clone())); + let asset_definition_id: AssetDefinitionId = "xor#domain".parse()?; let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); iroha_client @@ -33,8 +30,7 @@ fn long_multiple_blocks_created() { create_domain.into(), create_account.into(), create_asset.into(), - ]) - .expect("Failed to prepare state."); + ])?; thread::sleep(pipeline_time); @@ -50,8 +46,7 @@ fn long_multiple_blocks_created() { )), ); iroha_client - .submit(mint_asset) - .expect("Failed to create asset."); + .submit(mint_asset)?; account_has_quantity += quantity; thread::sleep(pipeline_time / 4); } @@ -66,6 +61,6 @@ fn long_multiple_blocks_created() { asset.id().definition_id == asset_definition_id && *asset.value() == AssetValue::Quantity(account_has_quantity) }) - }) - .expect("Panic on case assertion failure."); + })?; + Ok(()) } diff --git a/client/tests/integration/multisignature_account.rs b/client/tests/integration/multisignature_account.rs index 0341446e915..f32cf1b77d1 100644 --- a/client/tests/integration/multisignature_account.rs +++ b/client/tests/integration/multisignature_account.rs @@ -17,8 +17,8 @@ fn transaction_signed_by_new_signatory_of_account_should_pass() -> Result<()> { let pipeline_time = Configuration::pipeline_time(); // Given - let account_id: AccountId = "alice@wonderland".parse().expect("Valid"); - let asset_definition_id: AssetDefinitionId = "xor#wonderland".parse().expect("Valid"); + let account_id: AccountId = "alice@wonderland".parse::()?.alice_key(); + let asset_definition_id: AssetDefinitionId = "xor#wonderland".parse()?; let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); let key_pair = KeyPair::generate()?; let add_signatory = MintBox::new( diff --git a/client/tests/integration/multisignature_transaction.rs b/client/tests/integration/multisignature_transaction.rs index 07650f8c0ca..e1dee7253a8 100644 --- a/client/tests/integration/multisignature_transaction.rs +++ b/client/tests/integration/multisignature_transaction.rs @@ -14,13 +14,13 @@ use super::Configuration; #[allow(clippy::too_many_lines)] #[ignore = "Multisignature is not working for now. See #2595"] #[test] -fn multisignature_transactions_should_wait_for_all_signatures() { +fn multisignature_transactions_should_wait_for_all_signatures() -> eyre::Result<()> { let (_rt, network, _) = ::start_test_with_runtime(4, 1); wait_for_genesis_committed(&network.clients(), 0); let pipeline_time = Configuration::pipeline_time(); - let alice_id = AccountId::from_str("alice@wonderland").expect("Valid"); let alice_key_pair = get_key_pair(); + let alice_id = Alias::from_str("alice@wonderland")?.key(alice_key_pair.public_key().clone()); let key_pair_2 = KeyPair::generate().expect("Failed to generate KeyPair."); let asset_definition_id = AssetDefinitionId::from_str("camomile#wonderland").expect("Valid"); let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); @@ -33,7 +33,7 @@ fn multisignature_transactions_should_wait_for_all_signatures() { key_pair_2.public_key().clone(), ], ) - .into(), + .into(), )), IdBox::AccountId(alice_id.clone()), ); @@ -110,4 +110,5 @@ fn multisignature_transactions_should_wait_for_all_signatures() { .find(|asset| *asset.id() == asset_id) .expect("Failed to find expected asset"); assert_eq!(AssetValue::Quantity(quantity), *camomile_asset.value()); + Ok(()) } diff --git a/client/tests/integration/non_mintable.rs b/client/tests/integration/non_mintable.rs index 5bc3cdbe26e..7ad582b9b0d 100644 --- a/client/tests/integration/non_mintable.rs +++ b/client/tests/integration/non_mintable.rs @@ -13,8 +13,8 @@ fn non_mintable_asset_can_be_minted_once_but_not_twice() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); // Given - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); - let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); + let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland")?; let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone()).mintable_once()); @@ -61,8 +61,8 @@ fn non_mintable_asset_cannot_be_minted_if_registered_with_non_zero_value() -> Re wait_for_genesis_committed(&vec![test_client.clone()], 0); // Given - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); - let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); + let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland")?; let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone()).mintable_once()); @@ -94,8 +94,8 @@ fn non_mintable_asset_can_be_minted_if_registered_with_zero_value() -> Result<() wait_for_genesis_committed(&vec![test_client.clone()], 0); // Given - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); - let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); + let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland")?; let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone()).mintable_once()); diff --git a/client/tests/integration/offline_peers.rs b/client/tests/integration/offline_peers.rs index f39e8a7ea66..88dc708bcd6 100644 --- a/client/tests/integration/offline_peers.rs +++ b/client/tests/integration/offline_peers.rs @@ -6,7 +6,7 @@ use test_network::*; use tokio::runtime::Runtime; #[test] -fn genesis_block_is_commited_with_some_offline_peers() { +fn genesis_block_is_commited_with_some_offline_peers() -> eyre::Result<()> { prepare_test_for_nextest!(); // Given let rt = Runtime::test(); @@ -15,16 +15,15 @@ fn genesis_block_is_commited_with_some_offline_peers() { wait_for_genesis_committed(&network.clients(), 1); //When - let alice_id: AccountId = "alice@wonderland".parse().expect("Valid"); + let alice_id: AccountId = "alice@wonderland".parse::()?.alice_key(); let alice_has_roses = 13; //Then let assets = iroha_client - .request(client::asset::by_account_id(alice_id)) - .expect("Failed to execute request."); + .request(client::asset::by_account_id(alice_id))?; let asset = assets .iter() - .find(|asset| asset.id().definition_id == "rose#wonderland".parse().expect("Valid")) - .unwrap(); + .find(|asset| asset.id().definition_id == ("rose#wonderland".parse()).expect("Valid")).ok_or(eyre::eyre!("Failed to find asset. "))?; assert_eq!(AssetValue::Quantity(alice_has_roses), *asset.value()); + Ok(()) } diff --git a/client/tests/integration/permissions.rs b/client/tests/integration/permissions.rs index 9b454ce01be..e7313caf325 100644 --- a/client/tests/integration/permissions.rs +++ b/client/tests/integration/permissions.rs @@ -10,6 +10,7 @@ use iroha_permissions_validators::{ public_blockchain::{self, key_value::CanSetKeyValueInUserAssets}, }; use test_network::{PeerBuilder, *}; +use eyre::{Result, WrapErr as _}; use super::Configuration; @@ -20,16 +21,16 @@ fn get_assets(iroha_client: &mut Client, id: &::Id) -> } #[test] -fn permissions_require_registration_before_grant() { +fn permissions_require_registration_before_grant() -> eyre::Result<()> { let (_rt, _peer, iroha_client) = ::new() .with_instruction_judge(public_blockchain::default_permissions()) .start_with_runtime(); wait_for_genesis_committed(&vec![iroha_client.clone()], 0); // Given - let alice_id = ::Id::from_str("alice@wonderland").expect("Valid"); - let token = PermissionToken::new("can_do_stuff".parse().expect("valid")); - + let alice_id = Alias::from_str("alice@wonderland")?.alice_key(); + let token = PermissionToken::new("can_do_stuff".parse()?); + let grant_permission = GrantBox::new(token.clone(), alice_id); let register_role = RegisterBox::new( Role::new("staff_that_does_stuff".parse().unwrap()).add_permission(token.clone()), @@ -38,8 +39,8 @@ fn permissions_require_registration_before_grant() { // We shouldn't be able to grant unregistered permission tokens // or roles containing unregistered permission tokens assert!(iroha_client - .submit_blocking(grant_permission.clone()) - .is_err()); + .submit_blocking(grant_permission.clone()) + .is_err()); assert!(iroha_client.submit_blocking(register_role.clone()).is_err()); let register_permission = RegisterBox::new(PermissionTokenDefinition::new( @@ -51,10 +52,11 @@ fn permissions_require_registration_before_grant() { // Should be okay after registering the token id. assert!(iroha_client.submit_blocking(grant_permission).is_ok()); assert!(iroha_client.submit_blocking(register_role).is_ok()); + Ok(()) } #[test] -fn permissions_disallow_asset_transfer() { +fn permissions_disallow_asset_transfer() -> eyre::Result<()> { let (_rt, _peer, mut iroha_client) = ::new() .with_instruction_judge(public_blockchain::default_permissions()) .start_with_runtime(); @@ -62,16 +64,15 @@ fn permissions_disallow_asset_transfer() { let pipeline_time = Configuration::pipeline_time(); // Given - let alice_id = ::Id::from_str("alice@wonderland").expect("Valid"); - let bob_id = ::Id::from_str("bob@wonderland").expect("Valid"); - let asset_definition_id: AssetDefinitionId = "xor#wonderland".parse().expect("Valid"); + let alice_id = Alias::from_str("alice@wonderland")?.alice_key(); + let bob_id = Alias::from_str("bob@wonderland")?.fresh_key(); + let asset_definition_id: AssetDefinitionId = "xor#wonderland".parse()?; let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); - let register_bob = RegisterBox::new(Account::new(bob_id.clone(), [])); + let register_bob = RegisterBox::new(Account::from_id(bob_id.clone())); let alice_start_assets = get_assets(&mut iroha_client, &alice_id); iroha_client - .submit_all(vec![create_asset.into(), register_bob.into()]) - .expect("Failed to prepare state."); + .submit_all(vec![create_asset.into(), register_bob.into()])?; thread::sleep(pipeline_time * 2); let quantity: u32 = 200; @@ -80,8 +81,7 @@ fn permissions_disallow_asset_transfer() { IdBox::AssetId(AssetId::new(asset_definition_id.clone(), bob_id.clone())), ); iroha_client - .submit(mint_asset) - .expect("Failed to create asset."); + .submit(mint_asset)?; thread::sleep(pipeline_time * 2); //When @@ -105,10 +105,11 @@ fn permissions_disallow_asset_transfer() { )); let alice_assets = get_assets(&mut iroha_client, &alice_id); assert_eq!(alice_assets, alice_start_assets); + Ok(()) } #[test] -fn permissions_disallow_asset_burn() { +fn permissions_disallow_asset_burn() -> eyre::Result<()> { let (_rt, _not_drop, mut iroha_client) = ::new() .with_instruction_judge(public_blockchain::default_permissions()) .start_with_runtime(); @@ -117,17 +118,17 @@ fn permissions_disallow_asset_burn() { // Given thread::sleep(pipeline_time * 5); - let alice_id = "alice@wonderland".parse().expect("Valid"); - let bob_id: ::Id = "bob@wonderland".parse().expect("Valid"); - let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); + let alice_id = "alice@wonderland".parse::()?.alice_key(); + let bob_id: ::Id = "bob@wonderland".parse::()?.fresh_key(); + let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland")?; let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); - let register_bob = RegisterBox::new(Account::new(bob_id.clone(), [])); + let register_bob = RegisterBox::new(Account::from_id(bob_id.clone())); let alice_start_assets = get_assets(&mut iroha_client, &alice_id); iroha_client .submit_all(vec![create_asset.into(), register_bob.into()]) - .expect("Failed to prepare state."); + .wrap_err("Failed to prepare state.")?; thread::sleep(pipeline_time * 2); @@ -162,10 +163,11 @@ fn permissions_disallow_asset_burn() { let alice_assets = get_assets(&mut iroha_client, &alice_id); assert_eq!(alice_assets, alice_start_assets); + Ok(()) } #[test] -fn account_can_query_only_its_own_domain() { +fn account_can_query_only_its_own_domain() -> Result<()> { let query_judge = JudgeBuilder::with_validator(private_blockchain::query::OnlyAccountsDomain) .at_least_one_allow() .build(); @@ -178,36 +180,36 @@ fn account_can_query_only_its_own_domain() { // Given thread::sleep(pipeline_time * 2); - let domain_id: DomainId = "wonderland".parse().expect("Valid"); - let new_domain_id: DomainId = "wonderland2".parse().expect("Valid"); + let domain_id: DomainId = "wonderland".parse()?; + let new_domain_id: DomainId = "wonderland2".parse()?; let register_domain = RegisterBox::new(Domain::new(new_domain_id.clone())); iroha_client - .submit(register_domain) - .expect("Failed to prepare state."); + .submit(register_domain)?; thread::sleep(pipeline_time * 2); // Alice can query the domain in which her account exists. assert!(iroha_client - .request(client::domain::by_id(domain_id)) - .is_ok()); + .request(client::domain::by_id(domain_id)) + .is_ok()); // Alice cannot query other domains. assert!(iroha_client - .request(client::domain::by_id(new_domain_id)) - .is_err()); + .request(client::domain::by_id(new_domain_id)) + .is_err()); + Ok(()) } #[test] // If permissions are checked after instruction is executed during validation this introduces // a potential security liability that gives an attacker a backdoor for gaining root access -fn permissions_checked_before_transaction_execution() { +fn permissions_checked_before_transaction_execution() -> eyre::Result<()> { let instruction_judge = JudgeBuilder::with_validator( private_blockchain::register::GrantedAllowedRegisterDomains.into_validator(), ) - .at_least_one_allow() - .build(); + .at_least_one_allow() + .build(); let (_rt, _not_drop, iroha_client) = ::new() .with_instruction_judge(Box::new(instruction_judge)) @@ -218,10 +220,10 @@ fn permissions_checked_before_transaction_execution() { // Grant instruction is not allowed Instruction::Grant(GrantBox::new( PermissionToken::from(private_blockchain::register::CanRegisterDomains::new()), - IdBox::AccountId("alice@wonderland".parse().expect("Valid")), + IdBox::AccountId("alice@wonderland".parse::()?.alice_key()), )), Instruction::Register(RegisterBox::new(Domain::new( - "new_domain".parse().expect("Valid"), + "new_domain".parse()?, ))), ]; @@ -232,44 +234,45 @@ fn permissions_checked_before_transaction_execution() { let root_cause = rejection_reason.root_cause().to_string(); assert!(root_cause.contains("Account does not have the needed permission token")); + Ok(()) } #[test] -fn permissions_differ_not_only_by_names() { +fn permissions_differ_not_only_by_names() -> eyre::Result<()> { let instruction_judge = JudgeBuilder::with_recursive_validator( public_blockchain::key_value::AssetSetOnlyForSignerAccount .or(public_blockchain::key_value::SetGrantedByAssetOwner.into_validator()), ) - .no_denies() - .build(); + .no_denies() + .build(); let (_rt, _not_drop, client) = ::new() .with_instruction_judge(Box::new(instruction_judge)) .with_query_judge(Box::new(DenyAll::new())) .start_with_runtime(); - let alice_id: ::Id = "alice@wonderland".parse().expect("Valid"); - let mouse_id: ::Id = "mouse@wonderland".parse().expect("Valid"); + let alice_id = "alice@wonderland".parse::()?.alice_key(); + let mouse_id = "mouse@wonderland".parse::()?.fresh_key(); // Registering `Store` asset definitions let hat_definition_id: ::Id = - "hat#wonderland".parse().expect("Valid"); + "hat#wonderland".parse()?; let new_hat_definition = AssetDefinition::store(hat_definition_id.clone()); let shoes_definition_id: ::Id = - "shoes#wonderland".parse().expect("Valid"); + "shoes#wonderland".parse()?; let new_shoes_definition = AssetDefinition::store(shoes_definition_id.clone()); client .submit_all_blocking([ RegisterBox::new(new_hat_definition).into(), RegisterBox::new(new_shoes_definition).into(), ]) - .expect("Failed to register new asset definitions"); + .wrap_err("Failed to register new asset definitions")?; // Registering mouse - let new_mouse_account = Account::new(mouse_id.clone(), []); + let new_mouse_account = Account::from_id(mouse_id.clone()); client .submit_blocking(RegisterBox::new(new_mouse_account)) - .expect("Failed to register mouse"); + .wrap_err("Failed to register mouse")?; // Granting permission to Alice to modify metadata in Mouse's hats let mouse_hat_id = ::Id::new(hat_definition_id, mouse_id.clone()); @@ -278,22 +281,22 @@ fn permissions_differ_not_only_by_names() { PermissionToken::from(CanSetKeyValueInUserAssets::new(mouse_hat_id.clone())), alice_id.clone(), )) - .expect("Failed grant permission to modify Mouse's hats"); + .wrap_err("Failed grant permission to modify Mouse's hats")?; // Checking that Alice can modify Mouse's hats ... client .submit_blocking(SetKeyValueBox::new( mouse_hat_id, - Name::from_str("color").expect("Valid"), + Name::from_str("color")?, "red".to_owned(), )) - .expect("Failed to modify Mouse's hats"); + .wrap_err("Failed to modify Mouse's hats")?; // ... but not shoes let mouse_shoes_id = ::Id::new(shoes_definition_id, mouse_id); let set_shoes_color = SetKeyValueBox::new( mouse_shoes_id.clone(), - Name::from_str("color").expect("Valid"), + Name::from_str("color")?, "yellow".to_owned(), ); let _err = client @@ -306,10 +309,11 @@ fn permissions_differ_not_only_by_names() { PermissionToken::from(CanSetKeyValueInUserAssets::new(mouse_shoes_id)), alice_id, )) - .expect("Failed grant permission to modify Mouse's shoes"); + .wrap_err("Failed grant permission to modify Mouse's shoes")?; // Checking that Alice can modify Mouse's shoes client .submit_blocking(set_shoes_color) - .expect("Failed to modify Mouse's shoes"); + .wrap_err("Failed to modify Mouse's shoes")?; + Ok(()) } diff --git a/client/tests/integration/queries/account.rs b/client/tests/integration/queries/account.rs index 8cb8a9b4bfe..552c114dc1e 100644 --- a/client/tests/integration/queries/account.rs +++ b/client/tests/integration/queries/account.rs @@ -14,7 +14,7 @@ fn find_accounts_with_asset() -> Result<()> { // Registering new asset definition let definition_id = - ::Id::from_str("test_coin#wonderland").expect("Valid"); + ::Id::from_str("test_coin#wonderland")?; let asset_definition = AssetDefinition::quantity(definition_id.clone()); test_client.submit_blocking(RegisterBox::new(asset_definition.clone()))?; @@ -25,11 +25,11 @@ fn find_accounts_with_asset() -> Result<()> { assert_eq!(received_asset_definition, asset_definition.clone().build()); let accounts: [AccountId; 5] = [ - "alice@wonderland".parse().expect("Valid"), - "mad_hatter@wonderland".parse().expect("Valid"), - "cheshire_cat@wonderland".parse().expect("Valid"), - "caterpillar@wonderland".parse().expect("Valid"), - "white_rabbit@wonderland".parse().expect("Valid"), + "alice@wonderland".parse::()?.alice_key(), + "mad_hatter@wonderland".parse::()?.fresh_key(), + "cheshire_cat@wonderland".parse::()?.fresh_key(), + "caterpillar@wonderland".parse::()?.fresh_key(), + "white_rabbit@wonderland".parse::()?.fresh_key(), ]; // Registering accounts @@ -37,7 +37,7 @@ fn find_accounts_with_asset() -> Result<()> { .iter() .skip(1) // Alice has already been registered in genesis .cloned() - .map(|account_id| RegisterBox::new(Account::new(account_id, [])).into()) + .map(|account_id| RegisterBox::new(Account::from_id(account_id)).into()) .collect::>(); test_client.submit_all_blocking(register_accounts)?; diff --git a/client/tests/integration/queries/role.rs b/client/tests/integration/queries/role.rs index 752a9d7cd8e..fcdc396c3d4 100644 --- a/client/tests/integration/queries/role.rs +++ b/client/tests/integration/queries/role.rs @@ -122,7 +122,7 @@ fn find_roles_by_account_id() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); let role_ids = create_role_ids(); - let alice_id: ::Id = "alice@wonderland".parse().expect("Valid"); + let alice_id: ::Id = "alice@wonderland".parse::()?.alice_key(); // Registering roles let register_roles = role_ids diff --git a/client/tests/integration/query_errors.rs b/client/tests/integration/query_errors.rs index 07f144493cc..d48a4510e49 100644 --- a/client/tests/integration/query_errors.rs +++ b/client/tests/integration/query_errors.rs @@ -5,15 +5,16 @@ use std::str::FromStr; use iroha_client::client::{self, ClientQueryError}; use iroha_core::smartcontracts::{isi::query::Error as QueryError, FindError}; use iroha_data_model::prelude::*; +use test_network::FreshKeyTrait as _; #[test] fn non_existent_account_is_specific_error() { let (_rt, _peer, client) = ::new().start_with_runtime(); - // we cannot wait for genesis committment + // we don't need to wait for genesis to be committed. let err = client .request(client::account::by_id( - AccountId::from_str("john_doe@regalia").unwrap(), + Alias::from_str("john_doe@regalia").expect("valid name").fresh_key(), )) .expect_err("Should error"); @@ -24,4 +25,5 @@ fn non_existent_account_is_specific_error() { }, x => panic!("Unexpected error: {:?}", x), }; + todo!() } diff --git a/client/tests/integration/restart_peer.rs b/client/tests/integration/restart_peer.rs index 50854d1f111..546e224cb49 100644 --- a/client/tests/integration/restart_peer.rs +++ b/client/tests/integration/restart_peer.rs @@ -21,8 +21,8 @@ fn restarted_peer_should_have_the_same_asset_amount() -> Result<()> { let mut peer = ::new()?; configuration.sumeragi.trusted_peers.peers = std::iter::once(peer.id.clone()).collect(); - let account_id = AccountId::from_str("alice@wonderland").unwrap(); - let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").unwrap(); + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); + let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland")?; let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); let quantity: u32 = 200; diff --git a/client/tests/integration/roles.rs b/client/tests/integration/roles.rs index 97fc73ca4a4..bf9f9ec0c68 100644 --- a/client/tests/integration/roles.rs +++ b/client/tests/integration/roles.rs @@ -31,8 +31,8 @@ fn add_role_to_limit_transfer_count() -> Result<()> { .start_with_runtime(); wait_for_genesis_committed(&vec![test_client.clone()], 0); - let alice_id = ::Id::from_str("alice@wonderland")?; - let mouse_id = ::Id::from_str("mouse@wonderland")?; + let alice_id = Alias::from_str("alice@wonderland")?.alice_key(); + let mouse_id = Alias::from_str("mouse@wonderland")?.fresh_key(); let rose_definition_id = ::Id::from_str("rose#wonderland")?; let alice_rose_id = ::Id::new(rose_definition_id.clone(), alice_id.clone()); @@ -44,7 +44,7 @@ fn add_role_to_limit_transfer_count() -> Result<()> { assert!(rose_value > COUNT + 1); // Registering Mouse - let register_mouse = RegisterBox::new(Account::new(mouse_id, [])); + let register_mouse = RegisterBox::new(Account::from_id(mouse_id)); test_client.submit_blocking(register_mouse)?; // Registering new role which sets `Transfer` execution count limit to @@ -110,8 +110,8 @@ fn register_role_with_empty_token_params() -> Result<()> { let (_rt, _peer, test_client) = ::new().start_with_runtime(); wait_for_genesis_committed(&vec![test_client.clone()], 0); - let role_id = "root".parse().expect("Valid"); - let token = PermissionToken::new("token".parse().expect("Valid")); + let role_id = "root".parse()?; + let token = PermissionToken::new("token".parse()?); let role = Role::new(role_id).add_permission(token); test_client.submit(RegisterBox::new(role))?; @@ -133,14 +133,14 @@ fn register_and_grant_role_for_metadata_access() -> Result<()> { let (_rt, _peer, test_client) = ::new().start_with_runtime(); wait_for_genesis_committed(&vec![test_client.clone()], 0); - let alice_id = ::Id::from_str("alice@wonderland")?; - let mouse_id = ::Id::from_str("mouse@wonderland")?; + let alice_id = Alias::from_str("alice@wonderland")?.alice_key(); // Registering Mouse let mouse_key_pair = KeyPair::generate()?; - let register_mouse = RegisterBox::new(Account::new( + + let mouse_id = Alias::from_str("mouse@wonderland")?.key(mouse_key_pair.public_key().clone()); + let register_mouse = RegisterBox::new(Account::from_id( mouse_id.clone(), - [mouse_key_pair.public_key().clone()], )); test_client.submit_blocking(register_mouse)?; @@ -161,7 +161,7 @@ fn register_and_grant_role_for_metadata_access() -> Result<()> { // Alice modifies Mouse's metadata let set_key_value = SetKeyValueBox::new( mouse_id, - Name::from_str("key").expect("Valid"), + Name::from_str("key")?, Value::String("value".to_owned()), ); test_client.submit_blocking(set_key_value)?; @@ -178,12 +178,12 @@ fn unregistered_role_removed_from_account() -> Result<()> { let (_rt, _peer, test_client) = ::new().start_with_runtime(); wait_for_genesis_committed(&vec![test_client.clone()], 0); - let role_id: ::Id = "root".parse().expect("Valid"); - let alice_id: ::Id = "alice@wonderland".parse().expect("Valid"); - let mouse_id: ::Id = "mouse@wonderland".parse().expect("Valid"); + let role_id: ::Id = "root".parse()?; + let alice_id = "alice@wonderland".parse::()?.alice_key(); + let mouse_id = "mouse@wonderland".parse::()?.fresh_key(); // Registering Mouse - let register_mouse = RegisterBox::new(Account::new(mouse_id.clone(), [])); + let register_mouse = RegisterBox::new(Account::from_id(mouse_id.clone())); test_client.submit_blocking(register_mouse)?; // Register root role diff --git a/client/tests/integration/sorting.rs b/client/tests/integration/sorting.rs index c1abf35a613..0845aba7d82 100644 --- a/client/tests/integration/sorting.rs +++ b/client/tests/integration/sorting.rs @@ -5,21 +5,22 @@ use std::str::FromStr as _; use iroha_client::client; use iroha_data_model::prelude::*; use test_network::*; +use eyre::Result; #[test] -fn correct_pagination_assets_after_creating_new_one() { +fn correct_pagination_assets_after_creating_new_one() -> Result<()> { let (_rt, _peer, test_client) = ::new().start_with_runtime(); - let sort_by_metadata_key = Name::from_str("sort").expect("Valid"); + let sort_by_metadata_key = Name::from_str("sort")?; - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); let mut assets = vec![]; let mut instructions: Vec = vec![]; for i in 0..10 { let asset_definition_id = - AssetDefinitionId::from_str(&format!("xor{}#wonderland", i)).expect("Valid"); + AssetDefinitionId::from_str(&format!("xor{}#wonderland", i))?; let asset_definition = AssetDefinition::store(asset_definition_id.clone()); let mut asset_metadata = Metadata::new(); asset_metadata @@ -44,8 +45,7 @@ fn correct_pagination_assets_after_creating_new_one() { } test_client - .submit_all_blocking(instructions) - .expect("Valid"); + .submit_all_blocking(instructions)?; let sorting = Sorting::by_metadata_key(sort_by_metadata_key.clone()); @@ -54,8 +54,7 @@ fn correct_pagination_assets_after_creating_new_one() { client::asset::by_account_id(account_id.clone()), Pagination::new(Some(1), Some(5)), sorting.clone(), - ) - .expect("Valid"); + )?; assert_eq!( res.output @@ -77,8 +76,7 @@ fn correct_pagination_assets_after_creating_new_one() { sort_by_metadata_key, Value::U128(10), MetadataLimits::new(10, 22), - ) - .expect("Valid"); + )?; let new_asset = Asset::new( AssetId::new(new_asset_definition_id, account_id.clone()), AssetValue::Store(new_asset_metadata), @@ -88,16 +86,14 @@ fn correct_pagination_assets_after_creating_new_one() { let create_asset = RegisterBox::new(new_asset.clone()); test_client - .submit_all_blocking(vec![create_asset_definition.into(), create_asset.into()]) - .expect("Valid"); + .submit_all_blocking(vec![create_asset_definition.into(), create_asset.into()])?; let res = test_client .request_with_pagination_and_sorting( client::asset::by_account_id(account_id), Pagination::new(Some(6), None), sorting, - ) - .expect("Valid"); + )?; let mut right = assets.into_iter().skip(5).take(5).collect::>(); @@ -113,13 +109,14 @@ fn correct_pagination_assets_after_creating_new_one() { .map(|asset| asset.id().definition_id.name.clone()) .collect::>() ); + Ok(()) } #[test] -fn correct_sorting_of_asset_definitions() { +fn correct_sorting_of_asset_definitions() -> Result<()> { let (_rt, _peer, test_client) = ::new().start_with_runtime(); - let sort_by_metadata_key = Name::from_str("test_sort").expect("Valid"); + let sort_by_metadata_key = Name::from_str("test_sort")?; // Test sorting asset definitions @@ -128,7 +125,7 @@ fn correct_sorting_of_asset_definitions() { for i in 0..10 { let asset_definition_id = - AssetDefinitionId::from_str(&format!("xor{}#wonderland", i)).expect("Valid"); + AssetDefinitionId::from_str(&format!("xor{}#wonderland", i))?; let mut asset_metadata = Metadata::new(); asset_metadata .insert_with_limits( @@ -180,7 +177,7 @@ fn correct_sorting_of_asset_definitions() { let mut instructions = vec![]; for i in 0..10 { - let account_id = AccountId::from_str(&format!("bob{}@wonderland", i)).expect("Valid"); + let account_id = Alias::from_str(&format!("bob{}@wonderland", i))?.fresh_key(); let mut account_metadata = Metadata::new(); account_metadata .insert_with_limits( @@ -189,7 +186,7 @@ fn correct_sorting_of_asset_definitions() { MetadataLimits::new(10, 27), ) .expect("Valid"); - let account = Account::new(account_id, []).with_metadata(account_metadata); + let account = Account::from_id(account_id).with_metadata(account_metadata); accounts.push(account.clone().build()); @@ -213,11 +210,10 @@ fn correct_sorting_of_asset_definitions() { .request_with_sorting( client::account::all(), Sorting::by_metadata_key(sort_by_metadata_key.clone()), - ) - .expect("Valid"); + )?; - let alice_id = AccountId::from_str("alice@wonderland").expect("Valid"); - let genesis_id = AccountId::from_str("genesis@genesis").expect("Valid"); + let alice_id = Alias::from_str("alice@wonderland")?.alice_key(); + let genesis_id = Alias::from_str("genesis@genesis")?.fresh_key(); assert_eq!( res.output @@ -237,15 +233,14 @@ fn correct_sorting_of_asset_definitions() { let mut instructions = vec![]; for i in 0..10 { - let domain_id = DomainId::from_str(&format!("neverland{}", i)).expect("Valid"); + let domain_id = DomainId::from_str(&format!("neverland{}", i))?; let mut domain_metadata = Metadata::new(); domain_metadata .insert_with_limits( sort_by_metadata_key.clone(), Value::U128(i), MetadataLimits::new(10, 27), - ) - .expect("Valid"); + )?; let domain = Domain::new(domain_id).with_metadata(domain_metadata); domains.push(domain.clone().build()); @@ -273,8 +268,8 @@ fn correct_sorting_of_asset_definitions() { ) .expect("Valid"); - let genesis_id = DomainId::from_str("genesis").expect("Valid"); - let wonderland_id = DomainId::from_str("wonderland").expect("Valid"); + let genesis_id = DomainId::from_str("genesis")?; + let wonderland_id = DomainId::from_str("wonderland")?; assert_eq!( res.output @@ -283,4 +278,5 @@ fn correct_sorting_of_asset_definitions() { .collect::>(), domains ); + Ok(()) } diff --git a/client/tests/integration/transfer_asset.rs b/client/tests/integration/transfer_asset.rs index e687b852fe1..141a81b2ae9 100644 --- a/client/tests/integration/transfer_asset.rs +++ b/client/tests/integration/transfer_asset.rs @@ -5,6 +5,7 @@ use iroha_core::prelude::*; use iroha_data_model::{prelude::*, Registered}; use iroha_primitives::fixed::Fixed; use test_network::*; +use std::str::FromStr as _; #[test] fn simulate_transfer_quantity() { @@ -50,13 +51,18 @@ fn simulate_transfer< { let (_rt, _peer, mut iroha_client) = ::new().start_with_runtime(); wait_for_genesis_committed(&vec![iroha_client.clone()], 0); + let alice_id = { + let alias = Alias::from_str("alice@wonderland").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let mouse_id = { + let alias = Alias::from_str("mouse@wonderland").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; - let alice_id: AccountId = "alice@wonderland".parse().expect("Valid"); - let mouse_id: AccountId = "mouse@wonderland".parse().expect("Valid"); - let (bob_public_key, _) = KeyPair::generate() - .expect("Failed to generate KeyPair") - .into(); - let create_mouse = RegisterBox::new(Account::new(mouse_id.clone(), [bob_public_key])); + let create_mouse = RegisterBox::new(Account::from_id(mouse_id.clone())); let asset_definition_id: AssetDefinitionId = "camomile#wonderland".parse().expect("Valid"); let create_asset = RegisterBox::new(value_type(asset_definition_id.clone())); let mint_asset = MintBox::new( diff --git a/client/tests/integration/triggers/by_call_trigger.rs b/client/tests/integration/triggers/by_call_trigger.rs index 2cfe1c0ca03..f5b49511567 100644 --- a/client/tests/integration/triggers/by_call_trigger.rs +++ b/client/tests/integration/triggers/by_call_trigger.rs @@ -16,7 +16,7 @@ fn call_execute_trigger() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); let asset_definition_id = "rose#wonderland".parse()?; - let account_id = "alice@wonderland".parse()?; + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); let asset_id = AssetId::new(asset_definition_id, account_id); let prev_value = get_asset_value(&mut test_client, asset_id.clone())?; @@ -41,7 +41,7 @@ fn execute_trigger_should_produce_event() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); let asset_definition_id = "rose#wonderland".parse()?; - let account_id: AccountId = "alice@wonderland".parse()?; + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); let asset_id = AssetId::new(asset_definition_id, account_id.clone()); let instruction = MintBox::new(1_u32, asset_id.clone()); @@ -77,7 +77,7 @@ fn infinite_recursion_should_produce_one_call_per_block() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); let asset_definition_id = "rose#wonderland".parse()?; - let account_id = "alice@wonderland".parse()?; + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); let asset_id = AssetId::new(asset_definition_id, account_id); let trigger_id = TriggerId::from_str(TRIGGER_NAME)?; let call_trigger = ExecuteTriggerBox::new(trigger_id); @@ -105,7 +105,7 @@ fn trigger_failure_should_not_cancel_other_triggers_execution() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); let asset_definition_id = "rose#wonderland".parse()?; - let account_id = AccountId::from_str("alice@wonderland")?; + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); let asset_id = AssetId::new(asset_definition_id, account_id.clone()); // Registering trigger that should fail on execution @@ -160,7 +160,7 @@ fn trigger_should_not_be_executed_with_zero_repeats_count() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); let asset_definition_id = "rose#wonderland".parse()?; - let account_id = AccountId::from_str("alice@wonderland")?; + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); let asset_id = AssetId::new(asset_definition_id, account_id.clone()); let trigger_id = as Identifiable>::Id::from_str("self_modifying_trigger")?; @@ -210,7 +210,7 @@ fn trigger_should_be_able_to_modify_its_own_repeats_count() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); let asset_definition_id = "rose#wonderland".parse()?; - let account_id = AccountId::from_str("alice@wonderland")?; + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); let asset_id = AssetId::new(asset_definition_id, account_id.clone()); let trigger_id = as Identifiable>::Id::from_str("self_modifying_trigger")?; @@ -255,7 +255,7 @@ fn unregister_trigger() -> Result<()> { let (_rt, _peer, test_client) = ::new().start_with_runtime(); wait_for_genesis_committed(&vec![test_client.clone()], 0); - let account_id = AccountId::from_str("alice@wonderland")?; + let account_id = Alias::from_str("alice@wonderland")?.alice_key(); // Registering trigger let trigger_id = as Identifiable>::Id::from_str("empty_trigger")?; diff --git a/client/tests/integration/triggers/data_trigger.rs b/client/tests/integration/triggers/data_trigger.rs index 9f39f9eee44..2578b2635d6 100644 --- a/client/tests/integration/triggers/data_trigger.rs +++ b/client/tests/integration/triggers/data_trigger.rs @@ -5,13 +5,15 @@ use iroha_client::client; use iroha_core::prelude::*; use iroha_data_model::prelude::*; use test_network::*; +pub use core::str::FromStr as _; + #[test] fn must_execute_both_triggers() -> Result<()> { let (_rt, _peer, mut test_client) = ::new().start_with_runtime(); wait_for_genesis_committed(&vec![test_client.clone()], 0); - let account_id: AccountId = "alice@wonderland".parse()?; + let account_id = "alice@wonderland".parse::()?.alice_key(); let asset_definition_id = "rose#wonderland".parse()?; let asset_id = AssetId::new(asset_definition_id, account_id.clone()); @@ -65,8 +67,8 @@ fn domain_scoped_trigger_must_be_executed_only_on_events_in_its_domain() -> Resu let create_neverland_domain = RegisterBox::new(Domain::new("neverland".parse()?)); - let account_id: AccountId = "sapporo@neverland".parse()?; - let create_sapporo_account = RegisterBox::new(Account::new(account_id.clone(), [])); + let account_id = "sapporo@neverland".parse::()?.fresh_key(); + let create_sapporo_account = RegisterBox::new(Account::from_id(account_id.clone())); let asset_definition_id: AssetDefinitionId = "sakura#neverland".parse()?; let create_sakura_asset_definition = diff --git a/client/tests/integration/triggers/event_trigger.rs b/client/tests/integration/triggers/event_trigger.rs index 2e758e5d353..2e89d197a4a 100644 --- a/client/tests/integration/triggers/event_trigger.rs +++ b/client/tests/integration/triggers/event_trigger.rs @@ -13,7 +13,11 @@ fn test_mint_asset_when_new_asset_definition_created() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); let asset_definition_id = "rose#wonderland".parse()?; - let account_id = ::Id::from_str("alice@wonderland")?; + let account_id = { + let alias = Alias::from_str("alice@wonderland").expect("valid name"); + let (public_key, _) = test_network::get_key_pair().into(); + AccountId::new(public_key, alias) + }; let asset_id = AssetId::new(asset_definition_id, account_id.clone()); let prev_value = get_asset_value(&mut test_client, asset_id.clone())?; diff --git a/client/tests/integration/triggers/time_trigger.rs b/client/tests/integration/triggers/time_trigger.rs index 05e7543db19..e40b81801fa 100644 --- a/client/tests/integration/triggers/time_trigger.rs +++ b/client/tests/integration/triggers/time_trigger.rs @@ -5,6 +5,7 @@ use std::{fs, str::FromStr as _, time::Duration}; use eyre::{Context, Result}; use iroha_client::client::{self, Client}; use iroha_core::block::DEFAULT_CONSENSUS_ESTIMATION_MS; +use iroha_crypto::KeyPair; use iroha_data_model::{prelude::*, transaction::WasmSmartContract}; use test_network::*; @@ -32,7 +33,11 @@ fn time_trigger_execution_count_error_should_be_less_than_10_percent() -> Result wait_for_genesis_committed(&vec![test_client.clone()], 0); let start_time = current_time(); - let account_id: AccountId = "alice@wonderland".parse().expect("Valid"); + let account_id = { + let alias = Alias::from_str("alice@wonderland").expect("valid name"); + let (public_key, _) = test_network::get_key_pair().into(); + AccountId::new(public_key, alias) + }; let asset_definition_id = "rose#wonderland".parse().expect("Valid"); let asset_id = AssetId::new(asset_definition_id, account_id.clone()); @@ -88,7 +93,11 @@ fn change_asset_metadata_after_1_sec() -> Result<()> { let asset_definition_id = ::Id::from_str("rose#wonderland").expect("Valid"); - let account_id = ::Id::from_str("alice@wonderland").expect("Valid"); + let account_id = { + let alias = Alias::from_str("alice@wonderland").expect("valid name"); + let (public_key, _) = test_network::get_key_pair().into(); + AccountId::new(public_key, alias) + }; let key = Name::from_str("petal")?; let schedule = TimeSchedule::starting_at(start_time + Duration::from_millis(PERIOD_MS)); @@ -127,7 +136,11 @@ fn pre_commit_trigger_should_be_executed() -> Result<()> { wait_for_genesis_committed(&vec![test_client.clone()], 0); let asset_definition_id = "rose#wonderland".parse().expect("Valid"); - let account_id: AccountId = "alice@wonderland".parse().expect("Valid"); + let account_id = { + let alias = Alias::from_str("alice@wonderland").expect("valid name"); + let (public_key, _) = test_network::get_key_pair().into(); + AccountId::new(public_key, alias) + }; let asset_id = AssetId::new(asset_definition_id, account_id.clone()); let mut prev_value = get_asset_value(&mut test_client, asset_id.clone())?; @@ -178,24 +191,41 @@ fn mint_nft_for_every_user_every_1_sec() -> Result<()> { let (_rt, _peer, mut test_client) = ::new().start_with_runtime(); wait_for_genesis_committed(&vec![test_client.clone()], 0); - let alice_id = "alice@wonderland" - .parse::<::Id>() - .expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@wonderland").expect("valid name"); + let (public_key, _) = test_network::get_key_pair().into(); + AccountId::new(public_key, alias) + }; - let accounts: Vec = vec![ - alice_id.clone(), - "mad_hatter@wonderland".parse().expect("Valid"), - "cheshire_cat@wonderland".parse().expect("Valid"), - "caterpillar@wonderland".parse().expect("Valid"), - "white_rabbit@wonderland".parse().expect("Valid"), - ]; + let accounts = { + let accounts: Vec = vec![ + "mad_hatter@wonderland".parse().expect("Valid"), + "cheshire_cat@wonderland".parse().expect("Valid"), + "caterpillar@wonderland".parse().expect("Valid"), + "white_rabbit@wonderland".parse().expect("Valid"), + ]; + + let keys = vec![1, 2, 3, 4].iter().map(|_| { + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + public_key + }).collect::>(); + + let mut out = accounts.iter().zip(keys).map(|(alias, key)| { + ::Id::new(key, alias.clone()) + }).collect::>(); + + out.insert(0, alice_id.clone()); + out + }; // Registering accounts let register_accounts = accounts .iter() .skip(1) // Alice has already been registered in genesis .cloned() - .map(|account_id| RegisterBox::new(Account::new(account_id, [])).into()) + .map(Account::from_id) + .map(RegisterBox::new) + .map(Into::into) .collect::>(); test_client.submit_all_blocking(register_accounts)?; @@ -204,7 +234,7 @@ fn mint_nft_for_every_user_every_1_sec() -> Result<()> { env!("OUT_DIR"), "/wasm32-unknown-unknown/release/create_nft_for_every_user_smartcontract.wasm" )) - .wrap_err("Can't read smartcontract")?; + .wrap_err("Can't read smartcontract")?; println!("wasm size is {} bytes", wasm.len()); // Registering trigger @@ -233,7 +263,7 @@ fn mint_nft_for_every_user_every_1_sec() -> Result<()> { // Checking results for account_id in accounts { let start_pattern = "nft_number_"; - let end_pattern = format!("_for_{}#{}", account_id.name, account_id.domain_id); + let end_pattern = format!("_for_{}#{}", account_id.alias.as_ref().expect("Valid").name, account_id.domain_id().expect("Valid")); let assets = test_client.request(client::asset::by_account_id(account_id.clone()))?; let count: u64 = assets .into_iter() diff --git a/client/tests/integration/tx_history.rs b/client/tests/integration/tx_history.rs index 54265a88cfe..5d9abfdfc51 100644 --- a/client/tests/integration/tx_history.rs +++ b/client/tests/integration/tx_history.rs @@ -16,7 +16,11 @@ fn client_has_rejected_and_acepted_txs_should_return_tx_history() { let pipeline_time = Configuration::pipeline_time(); // Given - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); + let account_id = { + let alias = Alias::from_str("alice@wonderland").expect("valid name"); + let (public_key, _) = get_key_pair().into(); + AccountId::new(public_key, alias) + }; let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); iroha_client diff --git a/client/tests/integration/tx_rollback.rs b/client/tests/integration/tx_rollback.rs index 96f0ca0ac44..5eaead49b00 100644 --- a/client/tests/integration/tx_rollback.rs +++ b/client/tests/integration/tx_rollback.rs @@ -16,7 +16,11 @@ fn client_sends_transaction_with_invalid_instruction_should_not_see_any_changes( let pipeline_time = Configuration::pipeline_time(); //When - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); + let account_id = { + let alias = Alias::from_str("alice@wonderland").expect("valid name"); + let (public_key, _) = test_network::get_key_pair().into(); + AccountId::new(public_key, alias) + }; let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); let wrong_asset_definition_id = AssetDefinitionId::from_str("ksor#wonderland").expect("Valid"); let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id)); diff --git a/client/tests/integration/unregister_peer.rs b/client/tests/integration/unregister_peer.rs index cdb35dbc467..151f7fe64c5 100644 --- a/client/tests/integration/unregister_peer.rs +++ b/client/tests/integration/unregister_peer.rs @@ -103,9 +103,10 @@ fn init() -> Result<( thread::sleep(pipeline_time * 2); iroha_logger::info!("Started"); let create_domain = RegisterBox::new(Domain::new("domain".parse().expect("Valid"))); - let account_id: AccountId = "account@domain".parse().expect("Valid"); + let alias: Alias = "account@domain".parse().expect("Valid"); let (public_key, _) = KeyPair::generate()?.into(); - let create_account = RegisterBox::new(Account::new(account_id.clone(), [public_key])); + let account_id = AccountId::new(public_key, alias); + let create_account = RegisterBox::new(Account::from_id(account_id.clone())); let asset_definition_id: AssetDefinitionId = "xor#domain".parse().expect("Valid"); let create_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); client.submit_all(vec![ diff --git a/client/tests/integration/unstable_network.rs b/client/tests/integration/unstable_network.rs index d1b43234819..394e82251ed 100644 --- a/client/tests/integration/unstable_network.rs +++ b/client/tests/integration/unstable_network.rs @@ -3,11 +3,14 @@ use std::{thread, time::Duration}; use iroha_client::client::{self, Client}; +use iroha_crypto::KeyPair; use iroha_data_model::prelude::*; use iroha_logger::Level; use test_network::*; use tokio::runtime::Runtime; +use std::str::FromStr as _; + use super::Configuration; const MAXIMUM_TRANSACTIONS_IN_BLOCK: u32 = 5; @@ -80,7 +83,11 @@ fn unstable_network( let pipeline_time = Configuration::pipeline_time(); - let account_id: AccountId = "alice@wonderland".parse().expect("Valid"); + let account_id = { + let alias = Alias::from_str("alice@wonderland").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let asset_definition_id: AssetDefinitionId = "camomile#wonderland".parse().expect("Valid"); let register_asset = RegisterBox::new(AssetDefinition::quantity(asset_definition_id.clone())); iroha_client diff --git a/client_cli/src/main.rs b/client_cli/src/main.rs index c68a45f0cb8..08800813e26 100644 --- a/client_cli/src/main.rs +++ b/client_cli/src/main.rs @@ -134,17 +134,12 @@ fn main() -> Result<()> { Configuration::from_str("config.json")? }; let Configuration(config) = config; - println!( - "User: {}@{}", - config.account_id.name, config.account_id.domain_id - ); + println!("{}", config.account_id); #[cfg(debug_assertions)] eprintln!( "{}", &serde_json::to_string(&config).wrap_err("Failed to serialize configuration.")? ); - #[cfg(not(debug_assertions))] - eprintln!("This is a release build, debug information omitted from messages"); subcommand.run(&config)?; Ok(()) } @@ -161,13 +156,10 @@ pub fn submit( ) -> Result<()> { let instruction = instruction.into(); let iroha_client = Client::new(cfg)?; - #[cfg(debug_assertions)] let err_msg = format!( "Failed to build transaction from instruction {:?}", instruction ); - #[cfg(not(debug_assertions))] - let err_msg = "Failed to build transaction."; let tx = iroha_client .build_transaction(vec![instruction].into(), metadata) .wrap_err(err_msg)?; @@ -186,10 +178,7 @@ pub fn submit( .wrap_err("Failed to show interactive prompt.")? => iroha_client.sign_transaction(original_transaction).wrap_err("Failed to sign transaction.")?, _ => tx, }; - #[cfg(debug_assertions)] let err_msg = format!("Failed to submit transaction {:?}", tx); - #[cfg(not(debug_assertions))] - let err_msg = "Failed to submit transaction."; iroha_client.submit_transaction(tx).wrap_err(err_msg)?; Ok(()) } @@ -343,7 +332,7 @@ mod account { pub struct Register { /// Id of account in form `name@domain_name' #[structopt(short, long)] - pub id: AccountId, + pub alias: Alias, /// Its public key #[structopt(short, long)] pub key: PublicKey, @@ -355,11 +344,11 @@ mod account { impl RunArgs for Register { fn run(self, cfg: &ClientConfiguration) -> Result<()> { let Self { - id, + alias, key, metadata: Metadata(metadata), } = self; - let create_account = RegisterBox::new(Account::new(id, [key])); + let create_account = RegisterBox::new(Account::new(alias, [key])); submit(create_account, cfg, metadata).wrap_err("Failed to register account") } } @@ -407,17 +396,18 @@ mod account { impl RunArgs for SignatureCondition { fn run(self, cfg: &ClientConfiguration) -> Result<()> { - let account = Account::new(cfg.account_id.clone(), []); - let Self { - condition: Signature(condition), - metadata: Metadata(metadata), - } = self; - submit( - MintBox::new(account, EvaluatesTo::new_unchecked(condition.into())), - cfg, - metadata, - ) - .wrap_err("Failed to set signature condition") + // let account = Account::new(cfg.account_id.clone(), []); + // let Self { + // condition: Signature(condition), + // metadata: Metadata(metadata), + // } = self; + // submit( + // MintBox::new(account, EvaluatesTo::new_unchecked(condition.into())), + // cfg, + // metadata, + // ) + // .wrap_err("Failed to set signature condition") + todo!() } } @@ -446,7 +436,7 @@ mod account { pub struct Grant { /// Account id #[structopt(short, long)] - pub id: ::Id, + pub id: Alias, /// The JSON file with a permission token #[structopt(short, long)] pub permission: Permission, @@ -481,8 +471,9 @@ mod account { permission, metadata: Metadata(metadata), } = self; - let grant = GrantBox::new(permission.0, id); - submit(grant, cfg, metadata).wrap_err("Failed to grant the permission to the account") + // let grant = GrantBox::new(permission.0, id); + // submit(grant, cfg, metadata).wrap_err("Failed to grant the permission to the account") + todo!() } } @@ -491,18 +482,19 @@ mod account { pub struct ListPermissions { /// Account id #[structopt(short, long)] - id: ::Id, + id: Alias, } impl RunArgs for ListPermissions { fn run(self, cfg: &ClientConfiguration) -> Result<()> { - let client = Client::new(cfg)?; - let find_all_permissions = FindPermissionTokensByAccountId { id: self.id.into() }; - let permissions = client - .request(find_all_permissions) - .wrap_err("Failed to get all account permissions")?; - println!("{:#?}", permissions); - Ok(()) + // let client = Client::new(cfg)?; + // let find_all_permissions = FindPermissionTokensByAccountId { id: self.id.into() }; + // let permissions = client + // .request(find_all_permissions) + // .wrap_err("Failed to get all account permissions")?; + // println!("{:#?}", permissions); + // Ok(()) + todo!() } } } @@ -581,7 +573,7 @@ mod asset { pub struct Mint { /// Account id where asset is stored (in form of `name@domain_name') #[structopt(long)] - pub account: AccountId, + pub account: Alias, /// Asset id from which to mint (in form of `name#domain_name') #[structopt(long)] pub asset: AssetDefinitionId, @@ -601,11 +593,12 @@ mod asset { quantity, metadata: Metadata(metadata), } = self; - let mint_asset = MintBox::new( - Value::U32(quantity), - IdBox::AssetId(AssetId::new(asset, account)), - ); - submit(mint_asset, cfg, metadata).wrap_err("Failed to mint asset of type `Value::U32`") + // let mint_asset = MintBox::new( + // Value::U32(quantity), + // IdBox::AssetId(AssetId::new(asset, account)), + // ); + // submit(mint_asset, cfg, metadata).wrap_err("Failed to mint asset of type `Value::U32`") + todo!() } } @@ -614,10 +607,10 @@ mod asset { pub struct Transfer { /// Account from which to transfer (in form `name@domain_name') #[structopt(short, long)] - pub from: AccountId, + pub from: Alias, /// Account from which to transfer (in form `name@domain_name') #[structopt(short, long)] - pub to: AccountId, + pub to: Alias, /// Asset id to transfer (in form like `name#domain_name') #[structopt(short, long)] pub asset_id: AssetDefinitionId, @@ -639,9 +632,9 @@ mod asset { metadata: Metadata(metadata), } = self; let transfer_asset = TransferBox::new( - IdBox::AssetId(AssetId::new(asset_id.clone(), from)), + AssetId::aliased(asset_id.clone(), from), Value::U32(quantity), - IdBox::AssetId(AssetId::new(asset_id, to)), + AssetId::aliased(asset_id, to), ); submit(transfer_asset, cfg, metadata).wrap_err("Failed to transfer asset") } @@ -652,7 +645,7 @@ mod asset { pub struct Get { /// Account where asset is stored (in form of `name@domain_name') #[structopt(long)] - pub account: AccountId, + pub account: Alias, /// Asset name to lookup (in form of `name#domain_name') #[structopt(long)] pub asset: AssetDefinitionId, @@ -662,12 +655,7 @@ mod asset { fn run(self, cfg: &ClientConfiguration) -> Result<()> { let Self { account, asset } = self; let iroha_client = Client::new(cfg)?; - let asset_id = AssetId::new(asset, account); - let value = iroha_client - .request(asset::by_id(asset_id)) - .wrap_err("Failed to get asset.")?; - println!("Get Asset result: {:?}", value); - Ok(()) + todo!() } } diff --git a/config/src/client.rs b/config/src/client.rs index b68ba524164..b739b71e832 100644 --- a/config/src/client.rs +++ b/config/src/client.rs @@ -135,7 +135,13 @@ impl Configuration { /// Account ID used by default for demo purposes #[allow(clippy::expect_used)] fn placeholder_account() -> ::Id { - AccountId::from_str("alice@wonderland").expect("Account ID not valid") + let primary_key = "ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" + .parse() + .expect("Public key not in mulithash format"); + AccountId { + primary_key, + alias: None + } } // TODO: Delete this after `LoadFromDisk` is implemented diff --git a/core/benches/kura.rs b/core/benches/kura.rs index 0f8888d71ba..058778021a6 100644 --- a/core/benches/kura.rs +++ b/core/benches/kura.rs @@ -17,8 +17,16 @@ use tokio::{fs, runtime::Runtime}; async fn measure_block_size_for_n_validators(n_validators: u32) { let dir = tempfile::tempdir().unwrap(); - let alice_id = AccountId::from_str("alice@test").expect("tested"); - let bob_id = AccountId::from_str("bob@test").expect("tested"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("tested"); let alice_xor_id = ::Id::new(xor_id.clone(), alice_id); let bob_xor_id = ::Id::new(xor_id, bob_id); @@ -29,7 +37,7 @@ async fn measure_block_size_for_n_validators(n_validators: u32) { }); let keypair = KeyPair::generate().expect("Failed to generate KeyPair."); let tx = Transaction::new( - AccountId::from_str("alice@wonderland").expect("checked"), + AccountId::new(keypair.public_key().clone(), Alias::from_str("alice@wonderland").expect("checked")), vec![transfer].into(), 1000, ) diff --git a/core/benches/validation.rs b/core/benches/validation.rs index a6447192fd4..b77578f1852 100644 --- a/core/benches/validation.rs +++ b/core/benches/validation.rs @@ -13,8 +13,8 @@ use iroha_data_model::prelude::*; const TRANSACTION_TIME_TO_LIVE_MS: u64 = 100_000; -const START_DOMAIN: &str = "start"; -const START_ACCOUNT: &str = "starter"; +const START_DOMAIN: &str = "looking_glass"; +const START_ACCOUNT: &str = "dormouse"; const TRANSACTION_LIMITS: TransactionLimits = TransactionLimits { max_instruction_number: 4096, @@ -30,7 +30,7 @@ fn build_test_transaction(keys: KeyPair) -> Transaction { .expect("Failed to generate KeyPair.") .into(); let create_account = RegisterBox::new(Account::new( - AccountId::new( + Alias::new( account_name.parse().expect("Valid"), domain_name.parse().expect("Valid"), ), @@ -64,7 +64,7 @@ fn build_test_wsv(keys: KeyPair) -> WorldStateView { WorldStateView::new({ let domain_id = DomainId::from_str(START_DOMAIN).expect("Valid"); let mut domain = Domain::new(domain_id).build(); - let account_id = AccountId::new( + let account_id = Alias::new( START_ACCOUNT.parse().expect("Valid"), START_DOMAIN.parse().expect("Valid"), ); @@ -198,7 +198,7 @@ fn validate_blocks(criterion: &mut Criterion) { // Prepare WSV let key_pair = KeyPair::generate().expect("Failed to generate KeyPair."); let domain_name = "global"; - let account_id = AccountId::new( + let account_id = Alias::new( "root".parse().expect("Valid"), domain_name.parse().expect("Valid"), ); diff --git a/core/src/genesis.rs b/core/src/genesis.rs index a41c44fe940..c545964d3aa 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -318,7 +318,7 @@ impl GenesisTransaction { isi: SmallVec(smallvec![ RegisterBox::new(Domain::new(domain_id.clone())).into(), RegisterBox::new(Account::new( - AccountId::new(account_name, domain_id), + iroha_data_model::account::Alias::new(account_name, domain_id), [public_key], )) .into() @@ -384,19 +384,20 @@ impl RawGenesisDomainBuilder { /// Add an account to this domain without a public key. /// Should only be used for testing. - #[must_use] - pub fn with_account_without_public_key(mut self, account_name: Name) -> Self { - let account_id = AccountId::new(account_name, self.domain_id.clone()); - self.transaction - .isi - .push(RegisterBox::new(Account::new(account_id, [])).into()); - self - } + // #[must_use] + // #[ignore = "No longer supported"] + // pub fn with_account_without_public_key(mut self, account_name: Name) -> Self { + // let account_id = AccountId::new(account_name, self.domain_id.clone()); + // self.transaction + // .isi + // .push(RegisterBox::new(Account::new(account_id, [])).into()); + // self + // } /// Add an account to this domain #[must_use] pub fn with_account(mut self, account_name: Name, public_key: PublicKey) -> Self { - let account_id = AccountId::new(account_name, self.domain_id.clone()); + let account_id = Alias::new(account_name, self.domain_id.clone()); let register = RegisterBox::new(Account::new(account_id, [public_key])); self.transaction.isi.push(register.into()); self @@ -443,85 +444,85 @@ mod tests { Ok(()) } - #[allow(clippy::unwrap_used)] - #[test] - fn genesis_block_builder_example() { - let public_key = "ed0120204e9593c3ffaf4464a6189233811c297dd4ce73aba167867e4fbd4f8c450acb"; - let mut genesis_builder = RawGenesisBlockBuilder::new(); - - genesis_builder = genesis_builder - .domain("wonderland".parse().unwrap()) - .with_account_without_public_key("alice".parse().unwrap()) - .with_account_without_public_key("bob".parse().unwrap()) - .finish_domain() - .domain("tulgey_wood".parse().unwrap()) - .with_account_without_public_key("Cheshire_Cat".parse().unwrap()) - .finish_domain() - .domain("meadow".parse().unwrap()) - .with_account("Mad_Hatter".parse().unwrap(), public_key.parse().unwrap()) - .with_asset("hats".parse().unwrap(), AssetValueType::BigQuantity) - .finish_domain(); - - let finished_genesis_block = genesis_builder.build(); - { - let domain_id: DomainId = "wonderland".parse().unwrap(); - assert_eq!( - finished_genesis_block.transactions[0].isi[0], - Instruction::from(RegisterBox::new(Domain::new(domain_id.clone()))) - ); - assert_eq!( - finished_genesis_block.transactions[0].isi[1], - RegisterBox::new(Account::new( - AccountId::new("alice".parse().unwrap(), domain_id.clone()), - [] - )) - .into() - ); - assert_eq!( - finished_genesis_block.transactions[0].isi[2], - RegisterBox::new(Account::new( - AccountId::new("bob".parse().unwrap(), domain_id), - [] - )) - .into() - ); - } - { - let domain_id: DomainId = "tulgey_wood".parse().unwrap(); - assert_eq!( - finished_genesis_block.transactions[0].isi[3], - Instruction::from(RegisterBox::new(Domain::new(domain_id.clone()))) - ); - assert_eq!( - finished_genesis_block.transactions[0].isi[4], - RegisterBox::new(Account::new( - AccountId::new("Cheshire_Cat".parse().unwrap(), domain_id), - [] - )) - .into() - ); - } - { - let domain_id: DomainId = "meadow".parse().unwrap(); - assert_eq!( - finished_genesis_block.transactions[0].isi[5], - Instruction::from(RegisterBox::new(Domain::new(domain_id.clone()))) - ); - assert_eq!( - finished_genesis_block.transactions[0].isi[6], - RegisterBox::new(Account::new( - AccountId::new("Mad_Hatter".parse().unwrap(), domain_id), - [public_key.parse().unwrap()], - )) - .into() - ); - assert_eq!( - finished_genesis_block.transactions[0].isi[7], - RegisterBox::new(AssetDefinition::big_quantity( - "hats#meadow".parse().unwrap() - )) - .into() - ); - } - } + // #[allow(clippy::unwrap_used)] + // #[test] + // fn genesis_block_builder_example() { + // let public_key = "ed0120204e9593c3ffaf4464a6189233811c297dd4ce73aba167867e4fbd4f8c450acb"; + // let mut genesis_builder = RawGenesisBlockBuilder::new(); + + // genesis_builder = genesis_builder + // .domain("wonderland".parse().unwrap()) + // .with_account_without_public_key("alice".parse().unwrap()) + // .with_account_without_public_key("bob".parse().unwrap()) + // .finish_domain() + // .domain("tulgey_wood".parse().unwrap()) + // .with_account_without_public_key("Cheshire_Cat".parse().unwrap()) + // .finish_domain() + // .domain("meadow".parse().unwrap()) + // .with_account("Mad_Hatter".parse().unwrap(), public_key.parse().unwrap()) + // .with_asset("hats".parse().unwrap(), AssetValueType::BigQuantity) + // .finish_domain(); + + // let finished_genesis_block = genesis_builder.build(); + // { + // let domain_id: DomainId = "wonderland".parse().unwrap(); + // assert_eq!( + // finished_genesis_block.transactions[0].isi[0], + // Instruction::from(RegisterBox::new(Domain::new(domain_id.clone()))) + // ); + // assert_eq!( + // finished_genesis_block.transactions[0].isi[1], + // RegisterBox::new(Account::new( + // Alias::new("alice".parse().unwrap(), domain_id.clone()), + // [] + // )) + // .into() + // ); + // assert_eq!( + // finished_genesis_block.transactions[0].isi[2], + // RegisterBox::new(Account::new( + // Alias::new("bob".parse().unwrap(), domain_id), + // [] + // )) + // .into() + // ); + // } + // { + // let domain_id: DomainId = "tulgey_wood".parse().unwrap(); + // assert_eq!( + // finished_genesis_block.transactions[0].isi[3], + // Instruction::from(RegisterBox::new(Domain::new(domain_id.clone()))) + // ); + // assert_eq!( + // finished_genesis_block.transactions[0].isi[4], + // RegisterBox::new(Account::new( + // Alias::new("Cheshire_Cat".parse().unwrap(), domain_id), + // [] + // )) + // .into() + // ); + // } + // { + // let domain_id: DomainId = "meadow".parse().unwrap(); + // assert_eq!( + // finished_genesis_block.transactions[0].isi[5], + // Instruction::from(RegisterBox::new(Domain::new(domain_id.clone()))) + // ); + // assert_eq!( + // finished_genesis_block.transactions[0].isi[6], + // RegisterBox::new(Account::new( + // Alias::new("Mad_Hatter".parse().unwrap(), domain_id), + // [public_key.parse().unwrap()], + // )) + // .into() + // ); + // assert_eq!( + // finished_genesis_block.transactions[0].isi[7], + // RegisterBox::new(AssetDefinition::big_quantity( + // "hats#meadow".parse().unwrap() + // )) + // .into() + // ); + // } + // } } diff --git a/core/src/queue.rs b/core/src/queue.rs index 960743dd270..9f14799b5e2 100644 --- a/core/src/queue.rs +++ b/core/src/queue.rs @@ -253,7 +253,7 @@ mod tests { use crate::{wsv::World, PeersIds}; fn accepted_tx( - account_id: &str, + account_alias: &str, proposed_ttl_ms: u64, key: KeyPair, ) -> VersionedAcceptedTransaction { @@ -261,13 +261,15 @@ mod tests { .take(16) .collect(); let instructions: Vec = vec![FailBox { message }.into()]; - let tx = Transaction::new( - AccountId::from_str(account_id).expect("Valid"), - instructions.into(), - proposed_ttl_ms, - ) - .sign(key) - .expect("Failed to sign."); + let account_id = AccountId::new( + key.public_key().clone(), + account_alias + .parse() + .expect("You should check for allowed characters in tests."), + ); + let tx = Transaction::new(account_id, instructions.into(), proposed_ttl_ms) + .sign(key) + .expect("Failed to sign."); let limits = TransactionLimits { max_instruction_number: 4096, max_wasm_size_bytes: 0, @@ -280,7 +282,7 @@ mod tests { signatures: impl IntoIterator, ) -> World { let domain_id = DomainId::from_str("wonderland").expect("Valid"); - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); + let account_id = Alias::from_str("alice@wonderland").expect("Valid"); let mut domain = Domain::new(domain_id).build(); let account = Account::new(account_id, signatures).build(); assert!(domain.add_account(account).is_none()); @@ -349,8 +351,11 @@ mod tests { let wsv = { let domain_id = DomainId::from_str("wonderland").expect("Valid"); let mut domain = Domain::new(domain_id.clone()).build(); - let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); - let mut account = Account::new(account_id, [key_pair.public_key().clone()]).build(); + let account_id = { + let alias = Alias::from_str("alice@wonderland").expect("Valid"); + AccountId::new(key_pair.public_key().clone(), alias) + }; + let mut account = Account::from_id(account_id).build(); account.set_signature_check_condition(SignatureCheckCondition(false.into())); assert!(domain.add_account(account).is_none()); @@ -393,7 +398,10 @@ mod tests { wsv, ); let tx = Transaction::new( - AccountId::from_str("alice@wonderland").expect("Valid"), + AccountId::new( + key_pairs[0].public_key().clone(), + Alias::from_str("alice@wonderland").expect("Valid"), + ), Vec::::new().into(), 100_000, ); diff --git a/core/src/smartcontracts/isi/account.rs b/core/src/smartcontracts/isi/account.rs index d99b200b07d..19249d5387c 100644 --- a/core/src/smartcontracts/isi/account.rs +++ b/core/src/smartcontracts/isi/account.rs @@ -339,6 +339,13 @@ pub mod query { } } + impl ValidQuery for FindAccountIdByAlias { + #[metrics("find_account_id_by_alias")] + fn execute(&self, wsv: &WorldStateView) -> Result { + todo!() + } + } + impl ValidQuery for FindPermissionTokensByAccountId { #[metrics(+"find_permission_tokens_by_account_id")] fn execute(&self, wsv: &WorldStateView) -> Result { @@ -393,8 +400,8 @@ pub mod query { let mut vec = Vec::new(); for domain in wsv.domains().iter() { for account in domain.accounts() { - if account.id().name == name { - vec.push(account.clone()) + if let Some(ref alias) = account.id().alias { + if alias.name == name { vec.push(account.clone()) } } } } diff --git a/core/src/smartcontracts/isi/asset.rs b/core/src/smartcontracts/isi/asset.rs index 5e9710628ca..47b8acac4fb 100644 --- a/core/src/smartcontracts/isi/asset.rs +++ b/core/src/smartcontracts/isi/asset.rs @@ -519,10 +519,14 @@ pub mod query { let mut assets = Vec::new(); for account in domain.accounts() { for asset in account.assets() { - if asset.id().account_id.domain_id == domain_id - && asset.id().definition_id == asset_definition_id - { - assets.push(asset.clone()) + if let Some(domain) = asset.id().account_id.domain_id() { + if *domain == domain_id + && asset.id().definition_id == asset_definition_id + { + assets.push(asset.clone()) + } + } else { + todo!() } } } diff --git a/core/src/smartcontracts/isi/domain.rs b/core/src/smartcontracts/isi/domain.rs index b7a7a0e226d..a192eb9f894 100644 --- a/core/src/smartcontracts/isi/domain.rs +++ b/core/src/smartcontracts/isi/domain.rs @@ -28,22 +28,26 @@ pub mod isi { let account: Account = self.object.build(); let account_id = account.id().clone(); - account_id - .name - .validate_len(wsv.config.ident_length_limits) - .map_err(Error::Validate)?; - - wsv.modify_domain(&account_id.domain_id.clone(), |domain| { - if domain.account(&account_id).is_some() { - return Err(Error::Repetition( - InstructionType::Register, - IdBox::AccountId(account_id), - )); - } + if let Some(ref alias) = account_id.alias { + alias + .name + .validate_len(wsv.config.ident_length_limits) + .map_err(Error::Validate)?; + + wsv.modify_domain(&alias.domain_id.clone(), |domain| { + if domain.account(&account_id).is_some() { + return Err(Error::Repetition( + InstructionType::Register, + IdBox::AccountId(account_id), + )); + } - domain.add_account(account); - Ok(DomainEvent::Account(AccountEvent::Created(account_id))) - }) + domain.add_account(account); + Ok(DomainEvent::Account(AccountEvent::Created(account_id))) + }) + } else { + todo!() + } } } @@ -58,7 +62,7 @@ pub mod isi { ) -> Result<(), Self::Error> { let account_id = self.object_id; - wsv.modify_domain(&account_id.domain_id.clone(), |domain| { + wsv.modify_domain(&account_id.domain_id().ok_or(Error::BareAccount)?.clone(), |domain| { if domain.remove_account(&account_id).is_none() { return Err(FindError::Account(account_id).into()); } diff --git a/core/src/smartcontracts/isi/mod.rs b/core/src/smartcontracts/isi/mod.rs index 99ae8221471..ab3db07f90b 100644 --- a/core/src/smartcontracts/isi/mod.rs +++ b/core/src/smartcontracts/isi/mod.rs @@ -47,6 +47,9 @@ pub mod error { /// Instruction execution error type #[derive(Debug, Error)] pub enum Error { + /// Bare accounts have no alias. Require an account with alias + #[error("Bare accounts have no alias. Require an account with alias")] + BareAccount, /// Failed to find some entity #[error("Failed to find. {0}")] Find(#[from] Box), @@ -614,9 +617,10 @@ mod tests { fn world_with_test_domains() -> Result { let mut domain = Domain::new(DomainId::from_str("wonderland")?).build(); - let account_id = AccountId::from_str("alice@wonderland")?; + let account_id = Alias::from_str("alice@wonderland")?; let (public_key, _) = KeyPair::generate()?.into(); - let account = Account::new(account_id.clone(), [public_key]).build(); + let account_id = AccountId::new(public_key, account_id); + let account = Account::from_id(account_id.clone()).build(); assert!(domain.add_account(account).is_none()); let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland")?; assert!(domain @@ -631,7 +635,11 @@ mod tests { #[test] fn asset_store() -> Result<()> { let wsv = WorldStateView::new(world_with_test_domains()?); - let account_id = AccountId::from_str("alice@wonderland")?; + let account_id = { + let alias = Alias::from_str("alice@wonderland")?; + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland")?; let asset_id = AssetId::new(asset_definition_id, account_id.clone()); SetKeyValueBox::new( @@ -659,7 +667,11 @@ mod tests { #[test] fn account_metadata() -> Result<()> { let wsv = WorldStateView::new(world_with_test_domains()?); - let account_id = AccountId::from_str("alice@wonderland")?; + let account_id = { + let alias = Alias::from_str("alice@wonderland")?; + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; SetKeyValueBox::new( IdBox::from(account_id.clone()), Name::from_str("Bytes")?, @@ -687,7 +699,11 @@ mod tests { fn asset_definition_metadata() -> Result<()> { let wsv = WorldStateView::new(world_with_test_domains()?); let definition_id = AssetDefinitionId::from_str("rose#wonderland")?; - let account_id = AccountId::from_str("alice@wonderland")?; + let account_id = { + let alias = Alias::from_str("alice@wonderland")?; + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; SetKeyValueBox::new( IdBox::from(definition_id.clone()), Name::from_str("Bytes")?, @@ -715,7 +731,11 @@ mod tests { fn domain_metadata() -> Result<()> { let wsv = WorldStateView::new(world_with_test_domains()?); let domain_id = DomainId::from_str("wonderland")?; - let account_id = AccountId::from_str("alice@wonderland")?; + let account_id = { + let alias = Alias::from_str("alice@wonderland")?; + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; SetKeyValueBox::new( IdBox::from(domain_id.clone()), Name::from_str("Bytes")?, @@ -741,7 +761,11 @@ mod tests { #[test] fn executing_unregistered_trigger_should_return_error() -> Result<()> { let wsv = WorldStateView::new(world_with_test_domains()?); - let account_id = AccountId::from_str("alice@wonderland")?; + let account_id = { + let alias = Alias::from_str("alice@wonderland")?; + let public_key = KeyPair::generate().expect("Valid").public_key().clone(); + AccountId::new(public_key.clone(), alias) + }; let trigger_id = TriggerId::from_str("test_trigger_id")?; assert!(matches!( @@ -757,16 +781,16 @@ mod tests { #[test] fn unauthorized_trigger_execution_should_return_error() -> Result<()> { let wsv = WorldStateView::new(world_with_test_domains()?); - let account_id = AccountId::from_str("alice@wonderland")?; - let fake_account_id = AccountId::from_str("fake@wonderland")?; + let alias = Alias::from_str("alice@wonderland")?; + let public_key = KeyPair::generate().expect("Valid").public_key().clone(); + let account_id = AccountId::new(public_key.clone(), alias); + + let fake_account_alias = Alias::from_str("fake@wonderland")?; + let fake_pub_key = KeyPair::generate().expect("Valid").public_key().clone(); + let fake_account_id = AccountId::new(fake_pub_key.clone(), fake_account_alias); let trigger_id = TriggerId::from_str("test_trigger_id")?; - // register fake account - let (public_key, _) = KeyPair::generate() - .expect("Failed to generate KeyPair") - .into(); - let register_account = - RegisterBox::new(Account::new(fake_account_id.clone(), [public_key])); + let register_account = RegisterBox::new(Account::from_id(fake_account_id.clone())); register_account.execute(account_id.clone(), &wsv)?; // register the trigger diff --git a/core/src/smartcontracts/isi/permissions/mod.rs b/core/src/smartcontracts/isi/permissions/mod.rs index 4ee466055b3..a7f44221d4f 100644 --- a/core/src/smartcontracts/isi/permissions/mod.rs +++ b/core/src/smartcontracts/isi/permissions/mod.rs @@ -329,6 +329,7 @@ mod tests { use std::{collections::BTreeSet, str::FromStr as _}; + use iroha_crypto::KeyPair; use iroha_data_model::{expression::prelude::*, isi::*}; use super::{judge::DenyAll, prelude::*, *}; @@ -367,8 +368,12 @@ mod tests { _instruction: &Instruction, _wsv: &WorldStateView, ) -> ValidatorVerdict { - if authority.name.as_ref() == "alice" { - ValidatorVerdict::Deny("Alice account is denied.".to_owned()) + if let Some(ref alice) = authority.alias { + if alice.name.as_ref() == "alice" { + ValidatorVerdict::Deny("Alice account is denied.".to_owned()) + } else { + ValidatorVerdict::Skip + } } else { ValidatorVerdict::Skip } @@ -455,8 +460,16 @@ mod tests { let instruction_fail = Instruction::Fail(FailBox { message: "fail message".to_owned(), }); - let account_bob = ::Id::from_str("bob@test").expect("Valid"); - let account_alice = ::Id::from_str("alice@test").expect("Valid"); + let account_bob = { + let alias = Alias::from_str("bob@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let account_alice = { + let alias = Alias::from_str("alice@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let wsv = WorldStateView::new(World::new()); assert!(permissions_validator .judge(&account_bob, &instruction_burn, &wsv) @@ -484,7 +497,11 @@ mod tests { }); let nested_instruction_sequence = Instruction::If(If::new(true, instruction_burn.clone()).into()); - let account_alice = ::Id::from_str("alice@test").expect("Valid"); + let account_alice = { + let alias = Alias::from_str("alice@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let wsv = WorldStateView::new(World::new()); assert!(permissions_validator .judge(&account_alice, &instruction_fail, &wsv) @@ -499,15 +516,23 @@ mod tests { #[test] pub fn granted_permission() -> eyre::Result<()> { - let alice_id = ::Id::from_str("alice@test")?; - let bob_id = ::Id::from_str("bob@test")?; + let alice_id = { + let alias = Alias::from_str("alice@test")?; + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test")?; + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone(), ); let instruction_burn: Instruction = BurnBox::new(Value::U32(10), alice_xor_id).into(); let mut domain = Domain::new(DomainId::from_str("test").expect("Valid")).build(); - let mut bob_account = Account::new(bob_id.clone(), []).build(); + let mut bob_account = Account::from_id(bob_id.clone()).build(); assert!(bob_account.add_permission(TestToken.into())); assert!(domain.add_account(bob_account).is_none()); let wsv = WorldStateView::new(World::with([domain], BTreeSet::new())); @@ -521,40 +546,41 @@ mod tests { #[test] pub fn check_query_permissions_nested() { - let instruction: Instruction = Pair::new( - TransferBox::new( - asset_id("btc", "crypto", "seller", "company"), - EvaluatesTo::new_evaluates_to_value( - Add::new( - EvaluatesTo::new_unchecked( - Expression::Query( - FindAssetQuantityById::new(AssetId::new( - AssetDefinitionId::from_str("btc2eth_rate#exchange") - .expect("Valid"), - AccountId::from_str("dex@exchange").expect("Valid"), - )) - .into(), - ) - .into(), - ), - 10_u32, - ) - .into(), - ), - asset_id("btc", "crypto", "buyer", "company"), - ), - TransferBox::new( - asset_id("eth", "crypto", "buyer", "company"), - 15_u32, - asset_id("eth", "crypto", "seller", "company"), - ), - ) - .into(); - let wsv = WorldStateView::new(World::new()); - let alice_id = ::Id::from_str("alice@test").expect("Valid"); - let judge = JudgeBuilder::with_validator(DenyAll::new().into_validator()) - .no_denies() - .build(); - assert!(check_query_in_instruction(&alice_id, &instruction, &wsv, &judge).is_err()) + // let instruction: Instruction = Pair::new( + // TransferBox::new( + // asset_id("btc", "crypto", "seller", "company"), + // EvaluatesTo::new_evaluates_to_value( + // Add::new( + // EvaluatesTo::new_unchecked( + // Expression::Query( + // FindAssetQuantityById::new(AssetId::new( + // AssetDefinitionId::from_str("btc2eth_rate#exchange") + // .expect("Valid"), + // Alias::from_str("dex@exchange").expect("Valid"), + // )) + // .into(), + // ) + // .into(), + // ), + // 10_u32, + // ) + // .into(), + // ), + // asset_id("btc", "crypto", "buyer", "company"), + // ), + // TransferBox::new( + // asset_id("eth", "crypto", "buyer", "company"), + // 15_u32, + // asset_id("eth", "crypto", "seller", "company"), + // ), + // ) + // .into(); + // let wsv = WorldStateView::new(World::new()); + // let alice_id = Alias::from_str("alice@test").expect("Valid"); + // let judge = JudgeBuilder::with_validator(DenyAll::new().into_validator()) + // .no_denies() + // .build(); + // assert!(check_query_in_instruction(&alice_id, &instruction, &wsv, &judge).is_err()) + todo!() } } diff --git a/core/src/smartcontracts/isi/query.rs b/core/src/smartcontracts/isi/query.rs index 2b885be3a32..552fd8eaa01 100644 --- a/core/src/smartcontracts/isi/query.rs +++ b/core/src/smartcontracts/isi/query.rs @@ -40,6 +40,9 @@ impl ValidQueryRequest { /// Query errors. #[derive(Error, Debug, Decode, Encode, IntoSchema)] pub enum Error { + /// Bare account not allowed in this context. Please add alias + #[error("Bare account not allowed in this context. Please add alias")] + BareAccount, /// Query cannot be decoded. #[error("Query cannot be decoded")] Decode(#[from] Box), @@ -76,6 +79,7 @@ impl ValidQuery for QueryBox { match self { FindAllAccounts(query) => query.execute_into_value(wsv), FindAccountById(query) => query.execute_into_value(wsv), + FindAccountIdByAlias(query) => query.execute_into_value(wsv), FindAccountsByName(query) => query.execute_into_value(wsv), FindAccountsByDomainId(query) => query.execute_into_value(wsv), FindAccountsWithAsset(query) => query.execute_into_value(wsv), @@ -132,13 +136,16 @@ mod tests { }; static ALICE_KEYS: Lazy = Lazy::new(|| KeyPair::generate().unwrap()); + static ALICE_ALIAS: Lazy = + Lazy::new(|| Alias::from_str("alice@wonderland").expect("Valid")); + static ALICE_ID: Lazy = - Lazy::new(|| AccountId::from_str("alice@wonderland").expect("Valid")); + Lazy::new(|| AccountId::new(ALICE_KEYS.public_key().clone(), ALICE_ALIAS.clone())); fn world_with_test_domains() -> World { let domain_id = DomainId::from_str("wonderland").expect("Valid"); let mut domain = Domain::new(domain_id).build(); - let account = Account::new(ALICE_ID.clone(), [ALICE_KEYS.public_key().clone()]).build(); + let account = Account::from_id(ALICE_ID.clone()).build(); assert!(domain.add_account(account).is_none()); let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland").expect("Valid"); assert!(domain @@ -153,7 +160,7 @@ mod tests { fn world_with_test_asset_with_metadata() -> World { let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland").expect("Valid"); let mut domain = Domain::new(DomainId::from_str("wonderland").expect("Valid")).build(); - let mut account = Account::new(ALICE_ID.clone(), [ALICE_KEYS.public_key().clone()]).build(); + let mut account = Account::from_id(ALICE_ID.clone()).build(); assert!(domain .add_asset_definition( AssetDefinition::quantity(asset_definition_id.clone()).build(), @@ -186,7 +193,7 @@ mod tests { )?; let mut domain = Domain::new(DomainId::from_str("wonderland")?).build(); - let account = Account::new(ALICE_ID.clone(), [ALICE_KEYS.public_key().clone()]) + let account = Account::from_id(ALICE_ID.clone()) .with_metadata(metadata) .build(); assert!(domain.add_account(account).is_none()); @@ -427,7 +434,7 @@ mod tests { let mut domain = Domain::new(DomainId::from_str("wonderland")?) .with_metadata(metadata) .build(); - let account = Account::new(ALICE_ID.clone(), [ALICE_KEYS.public_key().clone()]).build(); + let account = Account::from_id(ALICE_ID.clone()).build(); assert!(domain.add_account(account).is_none()); let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland")?; assert!(domain diff --git a/core/src/smartcontracts/wasm.rs b/core/src/smartcontracts/wasm.rs index ea1e16afa31..587b3c71900 100644 --- a/core/src/smartcontracts/wasm.rs +++ b/core/src/smartcontracts/wasm.rs @@ -609,9 +609,8 @@ mod tests { }; fn world_with_test_account(account_id: AccountId) -> World { - let domain_id = account_id.domain_id.clone(); - let (public_key, _) = KeyPair::generate().unwrap().into(); - let account = Account::new(account_id, [public_key]).build(); + let domain_id = account_id.domain_id().expect("Must have alias").clone(); + let account = Account::from_id(account_id).build(); let mut domain = Domain::new(domain_id).build(); assert!(domain.add_account(account).is_none()); @@ -658,13 +657,16 @@ mod tests { } #[test] - fn execute_instruction_exported() -> Result<(), Error> { - let account_id = AccountId::from_str("alice@wonderland")?; - let wsv = WorldStateView::new(world_with_test_account(account_id.clone())); + fn execute_instruction_exported() -> eyre::Result<()> { + let alias = Alias::from_str("alice@wonderland")?; + let (public_key, _) = KeyPair::generate()?.into(); + let addr = AccountId::new(public_key.clone(), alias); + let wsv = WorldStateView::new(world_with_test_account(addr.clone())); let isi_hex = { - let new_account_id = AccountId::from_str("mad_hatter@wonderland")?; - let register_isi = RegisterBox::new(Account::new(new_account_id, [])); + let new_account_alias = Alias::from_str("mad_hatter@wonderland")?; + let new_account_id = AccountId::new(public_key.clone(), new_account_alias); + let register_isi = RegisterBox::new(Account::from_id(new_account_id.clone())); encode_hex(Instruction::Register(register_isi)) }; @@ -687,16 +689,16 @@ mod tests { isi_len = isi_hex.len() / 3, ); let mut runtime = Runtime::new()?; - runtime - .execute(&wsv, account_id, wat) - .expect("Execution failed"); + runtime.execute(&wsv, addr, wat).wrap_err("Execution failed")?; Ok(()) } #[test] - fn execute_query_exported() -> Result<(), Error> { - let account_id = AccountId::from_str("alice@wonderland")?; + fn execute_query_exported() -> eyre::Result<()> { + let account_alias = Alias::from_str("alice@wonderland")?; + let (public_key, _) = KeyPair::generate()?.into(); + let account_id = AccountId::new(public_key.clone(), account_alias); let wsv = WorldStateView::new(world_with_test_account(account_id.clone())); let query_hex = { @@ -729,19 +731,23 @@ mod tests { let mut runtime = Runtime::new()?; runtime .execute(&wsv, account_id, wat) - .expect("Execution failed"); + .wrap_err("Execution failed")?; Ok(()) } #[test] - fn instruction_limit_reached() -> Result<(), Error> { - let account_id = AccountId::from_str("alice@wonderland")?; + fn instruction_limit_reached() -> eyre::Result<()> { + let account_alias = Alias::from_str("alice@wonderland")?; + let (pub_key, _) = KeyPair::generate()?.into(); + let account_id = AccountId::new(pub_key.clone(), account_alias); let wsv = WorldStateView::new(world_with_test_account(account_id.clone())); let isi_hex = { - let new_account_id = AccountId::from_str("mad_hatter@wonderland")?; - let register_isi = RegisterBox::new(Account::new(new_account_id, [])); + let new_account_id = Alias::from_str("mad_hatter@wonderland")?; + let new_account = + Account::from_id(AccountId::new(pub_key.clone(), new_account_id.clone())); + let register_isi = RegisterBox::new(new_account); encode_hex(Instruction::Register(register_isi)) }; @@ -779,9 +785,9 @@ mod tests { if let Error::ExportFnCall(trap) = res.expect_err("Execution should fail") { assert!(trap - .display_reason() - .to_string() - .starts_with("Number of instructions exceeds maximum(1)")); + .display_reason() + .to_string() + .starts_with("Number of instructions exceeds maximum(1)")); } Ok(()) @@ -789,12 +795,18 @@ mod tests { #[test] fn instructions_not_allowed() -> Result<(), Error> { - let account_id = AccountId::from_str("alice@wonderland")?; + let account_id = Alias::from_str("alice@wonderland")?; + let (primary_key, _) = KeyPair::generate().expect("Shouldn't fail").into(); + let account_id = AccountId::new(primary_key.clone(), account_id); let wsv = WorldStateView::new(world_with_test_account(account_id.clone())); let isi_hex = { - let new_account_id = AccountId::from_str("mad_hatter@wonderland")?; - let register_isi = RegisterBox::new(Account::new(new_account_id, [])); + let new_account_id = AccountId::new( + primary_key.clone(), + Alias::from_str("mad_hatter@wonderland")?, + ); + // TODO: this should fail + let register_isi = RegisterBox::new(Account::from_id(account_id.clone())); encode_hex(Instruction::Register(register_isi)) }; @@ -803,16 +815,13 @@ mod tests { (module ;; Import host function to execute (import "iroha" "{execute_fn_name}" - (func $exec_fn (param i32 i32)) - ) + (func $exec_fn (param i32 i32))) {memory_and_alloc} ;; Function which starts the smartcontract execution (func (export "{main_fn_name}") (param i32 i32) - (call $exec_fn (i32.const 0) (i32.const {isi_len})) - ) - ) + (call $exec_fn (i32.const 0) (i32.const {isi_len})))) "#, main_fn_name = export::WASM_MAIN_FN_NAME, execute_fn_name = import::EXECUTE_ISI_FN_NAME, @@ -832,9 +841,9 @@ mod tests { if let Error::ExportFnCall(trap) = res.expect_err("Execution should fail") { assert!(trap - .display_reason() - .to_string() - .starts_with("Transaction rejected due to insufficient authorisation")); + .display_reason() + .to_string() + .starts_with("Transaction rejected due to insufficient authorisation")); } Ok(()) @@ -842,7 +851,9 @@ mod tests { #[test] fn queries_not_allowed() -> Result<(), Error> { - let account_id = AccountId::from_str("alice@wonderland")?; + let alias = Alias::from_str("alice@wonderland")?; + let public_key = KeyPair::generate().expect("Valid").public_key().clone(); + let account_id = AccountId::new(public_key, alias); let wsv = WorldStateView::new(world_with_test_account(account_id.clone())); let query_hex = { diff --git a/core/src/tx.rs b/core/src/tx.rs index 1207d899b72..ddef84fbceb 100644 --- a/core/src/tx.rs +++ b/core/src/tx.rs @@ -114,8 +114,12 @@ impl TransactionValidator { // Therefore, this instruction execution validates before actually executing let wsv = WorldStateView::clone(&self.wsv); + let domain = account_id.domain_id().ok_or(TransactionRejectionReason::NotPermitted(NotPermittedFail { + reason: "Account not registered to any domain.".to_owned(), + }))?; + if !wsv - .domain(&account_id.domain_id) + .domain(domain) .map_err(|_e| { TransactionRejectionReason::NotPermitted(NotPermittedFail { reason: "Domain not found in Iroha".to_owned(), @@ -427,8 +431,12 @@ mod tests { message: "Will fail".to_owned(), } .into(); + let alias = Alias::from_str("root@global").expect("Valid"); + let public_key = KeyPair::generate().expect("Valid").public_key().clone(); + let addr = AccountId::new(public_key, alias); + let tx = Transaction::new( - AccountId::from_str("root@global").expect("Valid"), + addr, vec![inst; DEFAULT_MAX_INSTRUCTION_NUMBER as usize + 1].into(), 1000, ); diff --git a/core/src/wsv.rs b/core/src/wsv.rs index 3197448b021..c5322ec56fd 100644 --- a/core/src/wsv.rs +++ b/core/src/wsv.rs @@ -599,7 +599,7 @@ impl WorldStateView { id: &AccountId, f: impl FnOnce(&Account) -> T, ) -> Result { - let domain = self.domain(&id.domain_id)?; + let domain = self.domain(id.domain_id().ok_or(QueryError::BareAccount)?)?; let account = domain.account(id).ok_or(QueryError::Unauthorized)?; Ok(f(account)) } @@ -613,7 +613,7 @@ impl WorldStateView { id: &AccountId, f: impl FnOnce(&mut Account) -> Result, ) -> Result<(), Error> { - self.modify_domain(&id.domain_id, |domain| { + self.modify_domain(id.domain_id().ok_or(Error::BareAccount)?, |domain| { let account = domain .account_mut(id) .ok_or_else(|| FindError::Account(id.clone()))?; diff --git a/core/test_network/src/lib.rs b/core/test_network/src/lib.rs index b1e2bf1393d..5b7a7a523fc 100644 --- a/core/test_network/src/lib.rs +++ b/core/test_network/src/lib.rs @@ -77,7 +77,7 @@ pub fn get_key_pair() -> KeyPair { PublicKey::from_str( r#"ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0"#, ) - .expect("Public key not in mulithash format"), + .expect("Public key not in mulithash format"), PrivateKey::from_hex( Algorithm::Ed25519, "9AC47ABF 59B356E0 BD7DCBBB B4DEC080 E302156A 48CA907E 47CB6AEA 1D32719E 7233BFC8 9DCBD68C 19FDE6CE 61582252 98EC1131 B6A130D1 AEB454C1 AB5183C0", @@ -92,6 +92,37 @@ pub trait TestGenesis: Sized { fn test(submit_genesis: bool) -> Option; } +/// This trait is used to decorate [`AccountId`] and [`Alias`] to produce a quick and easy-to-use syntax for use in tests. +pub trait AliceKeyTrait { + type Result; + + fn alice_key(self) -> Self::Result; +} + +impl AliceKeyTrait for Alias { + type Result = ::Id; + + fn alice_key(self) -> Self::Result { + let (public_key, _) = get_key_pair().into(); + Self::Result::new(public_key, self) + } +} + +pub trait FreshKeyTrait { + type Result; + + fn fresh_key(self) -> Self::Result; +} + +impl FreshKeyTrait for Alias { + type Result = ::Id; + + fn fresh_key(self) -> Self::Result { + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + Self::Result::new(public_key, self) + } +} + impl TestGenesis for G { fn test(submit_genesis: bool) -> Option { let cfg = Configuration::test(); @@ -102,8 +133,11 @@ impl TestGenesis for G { ); let rose_definition_id = ::Id::from_str("rose#wonderland") .expect("valid names"); - let alice_id = - ::Id::from_str("alice@wonderland").expect("valid names"); + let alice_id = { + let alias = Alias::from_str("alice@wonderland").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let mint_rose_permission: PermissionToken = CanMintUserAssetDefinitions::new(rose_definition_id.clone()).into(); let burn_rose_permission: PermissionToken = @@ -119,7 +153,7 @@ impl TestGenesis for G { RegisterBox::new(AssetDefinition::quantity( AssetDefinitionId::from_str("rose#wonderland").expect("valid names"), )) - .into(), + .into(), ); genesis.transactions[0] .isi @@ -131,14 +165,14 @@ impl TestGenesis for G { RegisterBox::new(AssetDefinition::quantity( AssetDefinitionId::from_str("tulip#wonderland").expect("valid names"), )) - .into(), + .into(), ); genesis.transactions[0].isi.push( MintBox::new( Value::U32(13), IdBox::AssetId(AssetId::new(rose_definition_id, alice_id)), ) - .into(), + .into(), ); configure_world(); @@ -149,7 +183,7 @@ impl TestGenesis for G { &Some(cfg.genesis), &cfg.sumeragi.transaction_limits, ) - .expect("Failed to init genesis") + .expect("Failed to init genesis") } } @@ -244,7 +278,7 @@ where maximum_transactions_in_block, offline_peers, ) - .await + .await } /// Adds peer to network and waits for it to start block @@ -516,8 +550,8 @@ where broker, telemetry, ) - .await - .expect("Failed to start iroha"); + .await + .expect("Failed to start iroha"); let job_handle = iroha.start_as_task().unwrap(); sender.send(iroha).unwrap(); job_handle.await.unwrap().unwrap(); @@ -689,7 +723,7 @@ where query_validator, temp_dir, ) - .await; + .await; } /// Creates and starts a peer with preapplied arguments. @@ -715,7 +749,7 @@ where time::sleep(Duration::from_millis( configuration.sumeragi.pipeline_time_ms(), )) - .await; + .await; (peer, client) } @@ -809,7 +843,7 @@ pub trait TestClient: Sized { ) -> eyre::Result where R: ValidQuery + Into + Debug + Clone, - >::Error: Into, + >::Error: Into, R::Output: Clone + Debug; /// Submits instructions with polling @@ -824,7 +858,7 @@ pub trait TestClient: Sized { ) -> eyre::Result where R: ValidQuery + Into + Debug + Clone, - >::Error: Into, + >::Error: Into, R::Output: Clone + Debug; /// Polls request till predicate `f` is satisfied, with default period and max attempts. @@ -838,7 +872,7 @@ pub trait TestClient: Sized { ) -> eyre::Result where R: ValidQuery + Into + Debug + Clone, - >::Error: Into, + >::Error: Into, R::Output: Clone + Debug; /// Polls request till predicate `f` is satisfied with `period` and `max_attempts` supplied. @@ -854,7 +888,7 @@ pub trait TestClient: Sized { ) -> eyre::Result where R: ValidQuery + Into + Debug + Clone, - >::Error: Into, + >::Error: Into, R::Output: Clone + Debug; } @@ -983,7 +1017,7 @@ impl TestClient for Client { ) -> eyre::Result where R: ValidQuery + Into + Debug + Clone, - >::Error: Into, + >::Error: Into, R::Output: Clone + Debug, { self.submit(instruction) @@ -999,7 +1033,7 @@ impl TestClient for Client { ) -> eyre::Result where R: ValidQuery + Into + Debug + Clone, - >::Error: Into, + >::Error: Into, R::Output: Clone + Debug, { self.submit_all(instructions) @@ -1016,7 +1050,7 @@ impl TestClient for Client { ) -> eyre::Result where R: ValidQuery + Into + Debug + Clone, - >::Error: Into, + >::Error: Into, R::Output: Clone + Debug, { let mut query_result = None; @@ -1037,7 +1071,7 @@ impl TestClient for Client { ) -> eyre::Result where R: ValidQuery + Into + Debug + Clone, - >::Error: Into, + >::Error: Into, R::Output: Clone + Debug, { self.poll_request_with_period(request, Configuration::pipeline_time() / 2, 10, f) diff --git a/data_model/src/account.rs b/data_model/src/account.rs index 3f9ce64dd21..5b1c7652401 100644 --- a/data_model/src/account.rs +++ b/data_model/src/account.rs @@ -36,52 +36,26 @@ use crate::{ permissions::{PermissionToken, Permissions}, prelude::Asset, role::{prelude::RoleId, RoleIds}, - HasMetadata, Identifiable, Name, ParseError, PublicKey, Registered, + HasMetadata, Identifiable, Name, ParseError, PublicKey, Registered, value::Value, }; -/// `AccountsMap` provides an API to work with collection of key (`Id`) - value -/// (`Account`) pairs. +/// `AccountsMap` provides an API to work with collection of key +/// (`Alias`) - value (`Account`) pairs. pub type AccountsMap = btree_map::BTreeMap<::Id, Account>; // The size of the array must be fixed. If we use more than `1` we -// waste all of that space for all non-multisig accounts. If we -// have 1 signatory per account, we keep the signature on the -// stack. If we have more than 1, we keep everything on the -// heap. Thanks to the union feature, we're not wasting `8Bytes` -// of space, over `Vec`. +// waste all of that space for all non-multisig accounts. If we have 1 +// signatory per account, we keep the signature on the stack. If we +// have more than 1, we keep everything on the heap. Thanks to the +// union feature, we're not wasting `8Bytes` of space, over `Vec`. type Signatories = btree_set::BTreeSet; -/// Genesis account name. -pub const GENESIS_ACCOUNT_NAME: &str = "genesis"; - /// The context value name for transaction signatories. pub const TRANSACTION_SIGNATORIES_VALUE: &str = "transaction_signatories"; /// The context value name for account signatories. pub const ACCOUNT_SIGNATORIES_VALUE: &str = "account_signatories"; -/// Genesis account. Used to mainly be converted to ordinary `Account` struct. -#[derive(Debug, Decode, Encode, Deserialize, Serialize, IntoSchema)] -pub struct GenesisAccount { - public_key: PublicKey, -} - -impl GenesisAccount { - /// Returns `GenesisAccount` instance. - #[must_use] - pub const fn new(public_key: PublicKey) -> Self { - GenesisAccount { public_key } - } -} - -#[cfg(feature = "mutable_api")] -impl From for Account { - #[inline] - fn from(account: GenesisAccount) -> Self { - Account::new(Id::genesis(), [account.public_key]).build() - } -} - /// Condition which checks if the account has the right signatures. #[derive( Debug, @@ -128,7 +102,7 @@ impl Default for SignatureCheckCondition { EvaluatesTo::new_unchecked(ContextValue::new(TRANSACTION_SIGNATORIES_VALUE).into()), EvaluatesTo::new_unchecked(ContextValue::new(ACCOUNT_SIGNATORIES_VALUE).into()), ) - .into(), + .into(), ) } } @@ -191,13 +165,23 @@ impl HasMetadata for NewAccount { )] #[cfg_attr(feature = "ffi_import", iroha_ffi::ffi_import)] impl NewAccount { - fn new( - id: ::Id, - signatories: impl IntoIterator, - ) -> Self { + fn new(alias: Alias, signatories: impl IntoIterator) -> Self { + let mut sig = signatories.into_iter(); + let primary_key = sig + .next() + .expect("Must have at least one key. Verify before this function call"); // TODO: come up with a `NonEmptyIter` trait. + let id = ::Id::new(primary_key, alias); Self { id, - signatories: signatories.into_iter().collect(), + signatories: sig.collect(), + metadata: Metadata::default(), + } + } + + pub fn from_id(addr: Id) -> Self { + Self { + id: addr.clone(), + signatories: [addr.primary_key].into_iter().collect(), metadata: Metadata::default(), } } @@ -273,10 +257,10 @@ impl Registered for Account { )] #[cfg_attr(feature = "ffi_import", iroha_ffi::ffi_import)] impl Account { - /// Construct builder for [`Account`] identifiable by [`Id`] containing the given signatories. + /// Construct builder for [`Account`] identifiable by [`Alias`] containing the given signatories. #[must_use] pub fn new( - id: ::Id, + id: Alias, signatories: impl IntoIterator, ) -> ::With { ::With::new(id, signatories) @@ -342,13 +326,19 @@ impl Account { self.signatories.insert(signatory) } - /// Remove a signatory from the `Account` and return whether the signatory was present in the `Account` + pub fn from_id(addr: Id) -> ::With { + ::With::from_id(addr) + } + + /// Remove a signatory from the `Account` and return whether the + /// `signatory` was present in the `Account`. #[inline] pub fn remove_signatory(&mut self, signatory: &PublicKey) -> bool { self.signatories.remove(signatory) } - /// Return a mutable reference to the [`Asset`] corresponding to the asset id + /// Return a mutable reference to the [`Asset`] corresponding to + /// the `asset_id` #[inline] pub fn asset_mut(&mut self, asset_id: &AssetId) -> Option<&mut Asset> { self.assets.get_mut(asset_id) @@ -410,10 +400,11 @@ impl FromIterator for crate::Value { /// /// # Examples /// + /// ```rust -/// use iroha_data_model::account::Id; +/// use iroha_data_model::account::Alias; /// -/// let id = "user@company".parse::().expect("Valid"); +/// let id = "user@company".parse::().expect("No whitespace and proper format"); /// ``` #[derive( Debug, @@ -433,35 +424,74 @@ impl FromIterator for crate::Value { IntoSchema, )] #[display(fmt = "{name}@{domain_id}")] -pub struct Id { +pub struct Alias { /// [`Account`]'s name. pub name: Name, /// [`Account`]'s [`Domain`](`crate::domain::Domain`)'s id. pub domain_id: ::Id, } -impl Id { - /// Construct [`Id`] from an account `name` and a `domain_name` if +pub type Address = PublicKey; + +impl Alias { + /// Construct [`Alias`] from an account `name` and a `domain_name` if /// these names are valid. #[inline] + #[must_use] pub const fn new(name: Name, domain_id: ::Id) -> Self { Self { name, domain_id } } - /// Construct [`Id`] of the genesis account. #[inline] #[must_use] - pub fn genesis() -> Self { - #[allow(clippy::expect_used)] + pub fn key(self, key: PublicKey) -> Id { + Id::new(key, self) + } +} + +impl From for Alias { + fn from(_: Value) -> Self { + todo!() + } +} + +/// The actual address that is being used to find the account in the world. +#[derive( + Debug, + Display, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Decode, + Encode, + Deserialize, + Serialize, + IntoFfi, + TryFromReprC, + IntoSchema, +)] +#[display(fmt = "{alias:?}")] +pub struct Id { + /// The primary key used for identification. + pub primary_key: Address, + /// The alias used for old register-first identification of accounts. + pub alias: Option, +} + +impl Id { + pub fn new(primary_key: PublicKey, alias: Alias) -> Self { Self { - name: Name::from_str(GENESIS_ACCOUNT_NAME).expect("Valid"), - domain_id: DomainId::from_str(GENESIS_DOMAIN_NAME).expect("Valid"), + primary_key, + alias: Some(alias), } } } /// Account Identification is represented by `name@domain_name` string. -impl FromStr for Id { +impl FromStr for Alias { type Err = ParseError; fn from_str(string: &str) -> Result { @@ -475,7 +505,7 @@ impl FromStr for Id { if vector.len() != 2 { return Err(ParseError { - reason: "Id should have format `name@domain_name`", + reason: "Alias should have format `name@domain_name`", }); } Ok(Self { @@ -485,7 +515,67 @@ impl FromStr for Id { } } +pub mod genesis { + //! Genesis representation of accounts. + use super::*; + + /// Genesis account name. + pub const GENESIS_ACCOUNT_NAME: &str = "genesis"; + + pub trait Genesis { + fn genesis() -> Self; + } + + impl Genesis for Alias { + /// Construct [`Alias`] of the genesis account. + #[inline] + #[must_use] + fn genesis() -> Self { + #[allow(clippy::expect_used)] + Self { + name: Name::from_str(GENESIS_ACCOUNT_NAME).expect("Valid"), + domain_id: DomainId::from_str(GENESIS_DOMAIN_NAME).expect("Valid"), + } + } + } + + impl Genesis for Id { + fn genesis() -> Self { + todo!() + } + } + + impl Id { + pub fn domain_id(&self) -> Option<&crate::domain::Id> { + todo!() + } + } + + /// Genesis account. Used to mainly be converted to an ordinary + /// `Account` struct after the genesis round. + #[derive(Debug, Decode, Encode, Deserialize, Serialize, IntoSchema)] + pub struct GenesisAccount { + public_key: PublicKey, + } + + impl GenesisAccount { + /// Returns `GenesisAccount` instance. + #[must_use] + pub const fn new(public_key: PublicKey) -> Self { + GenesisAccount { public_key } + } + } + + #[cfg(feature = "mutable_api")] + impl From for Account { + #[inline] + fn from(account: GenesisAccount) -> Self { + Account::new(Alias::genesis(), [account.public_key]).build() + } + } +} + /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { - pub use super::{Account, Id as AccountId, SignatureCheckCondition}; + pub use super::{genesis::Genesis, Account, Alias, Id as AccountId, SignatureCheckCondition}; } diff --git a/data_model/src/asset.rs b/data_model/src/asset.rs index a1c13969522..8a302d5399c 100644 --- a/data_model/src/asset.rs +++ b/data_model/src/asset.rs @@ -22,8 +22,8 @@ use serde::{Deserialize, Serialize}; use strum::EnumString; use crate::{ - account::prelude::*, domain::prelude::*, ffi::ffi_item, metadata::Metadata, HasMetadata, - Identifiable, Name, ParseError, Registered, TryAsMut, TryAsRef, Value, + account::prelude::*, domain::prelude::*, ffi::ffi_item, metadata::Metadata, value::Value, + HasMetadata, Identifiable, Name, ParseError, Registered, TryAsMut, TryAsRef, prelude::EvaluatesTo, IdBox, }; /// [`AssetsMap`] provides an API to work with collection of key ([`Id`]) - value @@ -613,6 +613,14 @@ impl Id { account_id, } } + + #[inline] + pub const fn aliased( + definition_id: ::Id, + alias: Alias + ) -> EvaluatesTo { + todo!() + } } impl Registered for Asset { @@ -623,6 +631,7 @@ impl Registered for AssetDefinition { type With = NewAssetDefinition; } + impl FromIterator for Value { fn from_iter>(iter: T) -> Self { iter.into_iter() diff --git a/data_model/src/block_value.rs b/data_model/src/block_value.rs index 11f281f05aa..67af0b586d0 100644 --- a/data_model/src/block_value.rs +++ b/data_model/src/block_value.rs @@ -4,7 +4,10 @@ use alloc::{format, string::String, vec::Vec}; use core::cmp::Ordering; -use derive_more::Display; +#[cfg(not(target_arch = "aarch64"))] +use derive_more::Into; + +use derive_more::{AsRef, Deref, Display, From}; use iroha_crypto::{Hash, HashOf, MerkleTree}; use iroha_schema::IntoSchema; use parity_scale_codec::{Decode, Encode}; @@ -78,7 +81,74 @@ impl Ord for BlockValue { } } +impl From for crate::value::Value { + fn from(block_value: BlockValue) -> Self { + crate::value::Value::Block(block_value.into()) + } +} + +#[cfg(target_arch = "aarch64")] +impl From for BlockValue { + fn from(block_value: BlockValueWrapper) -> Self { + *block_value.0 + } +} + +impl IntoSchema for BlockValueWrapper { + fn type_name() -> String { + BlockValue::type_name() + } + + fn schema(map: &mut iroha_schema::MetaMap) { + BlockValue::schema(map); + } +} + +/// Cross-platform wrapper for `BlockValue`. +#[cfg(target_arch = "aarch64")] +#[derive( + AsRef, + Clone, + Debug, + Decode, + Deref, + Deserialize, + Encode, + Eq, + From, + Ord, + PartialEq, + PartialOrd, + Serialize, +)] +#[as_ref(forward)] +#[deref(forward)] +#[from(forward)] +#[serde(transparent)] +pub struct BlockValueWrapper(Box); + +/// Cross-platform wrapper for `BlockValue`. +#[cfg(not(target_arch = "aarch64"))] +#[derive( + AsRef, + Clone, + Debug, + Decode, + Deref, + Deserialize, + Encode, + Eq, + From, + Into, + Ord, + PartialEq, + PartialOrd, + Serialize, +)] +#[serde(transparent)] +pub struct BlockValueWrapper(BlockValue); + /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { - pub use super::{BlockHeaderValue, BlockValue}; + pub use super::{BlockHeaderValue, BlockValue, BlockValueWrapper}; } diff --git a/data_model/src/domain.rs b/data_model/src/domain.rs index ca843a61e78..71550c299c0 100644 --- a/data_model/src/domain.rs +++ b/data_model/src/domain.rs @@ -12,23 +12,23 @@ use core::str::FromStr; #[cfg(feature = "std")] use std::alloc::alloc; +pub use crate::ipfs::IpfsPath; use derive_more::{Display, FromStr}; use getset::{Getters, MutGetters}; use iroha_crypto::PublicKey; use iroha_data_model_derive::IdOrdEqHash; use iroha_ffi::{IntoFfi, TryFromReprC}; -use iroha_primitives::conststr::ConstString; use iroha_schema::IntoSchema; -use parity_scale_codec::{Decode, Encode, Input}; +use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; use crate::{ - account::{Account, AccountsMap}, + account::{genesis::Genesis as _, Account, AccountsMap}, asset::AssetDefinitionsMap, ffi::ffi_item, metadata::Metadata, prelude::{AssetDefinition, AssetDefinitionEntry}, - HasMetadata, Identifiable, Name, ParseError, Registered, + HasMetadata, Identifiable, Name, Registered, }; /// The domain name of the genesis domain. @@ -64,7 +64,7 @@ impl From for Domain { id: Id::from_str(GENESIS_DOMAIN_NAME).expect("Valid"), accounts: core::iter::once(( ::Id::genesis(), - crate::account::GenesisAccount::new(domain.genesis_key).into(), + crate::account::genesis::GenesisAccount::new(domain.genesis_key).into(), )) .collect(), asset_definitions: btree_map::BTreeMap::default(), @@ -336,108 +336,6 @@ impl FromIterator for crate::Value { } } -/// Represents path in IPFS. Performs checks to ensure path validity. -/// Construct using [`FromStr::from_str`] method. -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Encode, - Serialize, - IntoFfi, - TryFromReprC, - IntoSchema, -)] -pub struct IpfsPath(ConstString); - -impl FromStr for IpfsPath { - type Err = ParseError; - - fn from_str(string: &str) -> Result { - let mut subpath = string.split('/'); - let path_segment = subpath.next().ok_or(ParseError { - reason: "Impossible error: first value of str::split() always has value", - })?; - - if path_segment.is_empty() { - let root_type = subpath.next().ok_or(ParseError { - reason: "Expected root type, but nothing found", - })?; - let key = subpath.next().ok_or(ParseError { - reason: "Expected at least one content id", - })?; - - match root_type { - "ipfs" | "ipld" => Self::check_cid(key)?, - "ipns" => (), - _ => { - return Err(ParseError { - reason: "Unexpected root type. Expected `ipfs`, `ipld` or `ipns`", - }) - } - } - } else { - // by default if there is no prefix it's an ipfs or ipld path - Self::check_cid(path_segment)?; - } - - for path in subpath { - Self::check_cid(path)?; - } - - Ok(IpfsPath(ConstString::from(string))) - } -} - -impl AsRef for IpfsPath { - #[inline] - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl IpfsPath { - /// Superficially checks IPFS `cid` (Content Identifier) - #[inline] - const fn check_cid(cid: &str) -> Result<(), ParseError> { - if cid.len() < 2 { - return Err(ParseError { - reason: "IPFS cid is too short", - }); - } - - Ok(()) - } -} - -impl<'de> Deserialize<'de> for IpfsPath { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - #[cfg(not(feature = "std"))] - use alloc::borrow::Cow; - #[cfg(feature = "std")] - use std::borrow::Cow; - - use serde::de::Error as _; - - let name = >::deserialize(deserializer)?; - Self::from_str(&name).map_err(D::Error::custom) - } -} - -impl Decode for IpfsPath { - fn decode(input: &mut I) -> Result { - let name = ConstString::decode(input)?; - Self::from_str(&name).map_err(|error| error.reason.into()) - } -} - /// Identification of a [`Domain`]. #[derive( Debug, @@ -478,75 +376,3 @@ impl Id { pub mod prelude { pub use super::{Domain, GenesisDomain, Id as DomainId, GENESIS_DOMAIN_NAME}; } - -#[cfg(test)] -mod tests { - #![allow(clippy::restriction)] - - use super::*; - - const INVALID_IPFS: [&str; 4] = [ - "", - "/ipld", - "/ipfs/a", - "/ipfsssss/QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE", - ]; - - #[test] - fn test_invalid_ipfs_path() { - assert!(matches!( - IpfsPath::from_str(INVALID_IPFS[0]), - Err(err) if err.to_string() == "Expected root type, but nothing found" - )); - assert!(matches!( - IpfsPath::from_str(INVALID_IPFS[1]), - Err(err) if err.to_string() == "Expected at least one content id" - )); - assert!(matches!( - IpfsPath::from_str(INVALID_IPFS[2]), - Err(err) if err.to_string() == "IPFS cid is too short" - )); - assert!(matches!( - IpfsPath::from_str(INVALID_IPFS[3]), - Err(err) if err.to_string() == "Unexpected root type. Expected `ipfs`, `ipld` or `ipns`" - )); - } - - #[test] - #[allow(clippy::expect_used)] - fn test_valid_ipfs_path() { - // Valid paths - IpfsPath::from_str("QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE") - .expect("Path without root should be valid"); - IpfsPath::from_str("/ipfs/QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE") - .expect("Path with ipfs root should be valid"); - IpfsPath::from_str("/ipld/QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE") - .expect("Path with ipld root should be valid"); - IpfsPath::from_str("/ipns/QmSrPmbaUKA3ZodhzPWZnpFgcPMFWF4QsxXbkWfEptTBJd") - .expect("Path with ipns root should be valid"); - IpfsPath::from_str("/ipfs/SomeFolder/SomeImage") - .expect("Path with folders should be valid"); - } - - #[test] - fn deserialize_ipfs() { - for invalid_ipfs in INVALID_IPFS { - let invalid_ipfs = IpfsPath(invalid_ipfs.into()); - let serialized = serde_json::to_string(&invalid_ipfs).expect("Valid"); - let ipfs = serde_json::from_str::(serialized.as_str()); - - assert!(ipfs.is_err()); - } - } - - #[test] - fn decode_ipfs() { - for invalid_ipfs in INVALID_IPFS { - let invalid_ipfs = IpfsPath(invalid_ipfs.into()); - let bytes = invalid_ipfs.encode(); - let ipfs = IpfsPath::decode(&mut &bytes[..]); - - assert!(ipfs.is_err()); - } - } -} diff --git a/data_model/src/events/data/events.rs b/data_model/src/events/data/events.rs index 8365c7915be..376acc397ea 100644 --- a/data_model/src/events/data/events.rs +++ b/data_model/src/events/data/events.rs @@ -280,13 +280,13 @@ mod account { match self { Self::Asset(asset) => &asset.origin_id().account_id, Self::Created(id) - | Self::Deleted(id) - | Self::AuthenticationAdded(id) - | Self::AuthenticationRemoved(id) - | Self::PermissionAdded(id) - | Self::PermissionRemoved(id) - | Self::RoleRevoked(id) - | Self::RoleGranted(id) + | Self::Deleted(id) + | Self::AuthenticationAdded(id) + | Self::AuthenticationRemoved(id) + | Self::PermissionAdded(id) + | Self::PermissionRemoved(id) + | Self::RoleRevoked(id) + | Self::RoleGranted(id) | Self::MetadataInserted(id) | Self::MetadataRemoved(id) => id, } @@ -331,7 +331,7 @@ mod domain { fn origin_id(&self) -> &::Id { match self { - Self::Account(account) => &account.origin_id().domain_id, + Self::Account(account) => &account.origin_id().domain_id().expect("Unimplemented"), Self::AssetDefinition(asset_definition) => &asset_definition.origin_id().domain_id, Self::Created(id) | Self::Deleted(id) @@ -461,7 +461,7 @@ impl Event { pub fn domain_id(&self) -> Option<&::Id> { match self { Self::Domain(event) => Some(event.origin_id()), - Self::Account(event) => Some(&event.origin_id().domain_id), + Self::Account(event) => event.origin_id().domain_id(), Self::AssetDefinition(event) => Some(&event.origin_id().domain_id), Self::Asset(event) => Some(&event.origin_id().definition_id.domain_id), Self::Trigger(event) => event.origin_id().domain_id.as_ref(), diff --git a/data_model/src/events/data/filters.rs b/data_model/src/events/data/filters.rs index 1509e465b9b..6f4ff99f8bd 100644 --- a/data_model/src/events/data/filters.rs +++ b/data_model/src/events/data/filters.rs @@ -176,6 +176,8 @@ pub mod prelude { #[cfg(test)] mod tests { + use iroha_crypto::KeyPair; + use super::*; #[test] @@ -186,7 +188,9 @@ mod tests { let asset_name = "rose".parse().expect("Valid"); let domain_id = DomainId::new(domain_name); - let account_id = AccountId::new(account_name, domain_id.clone()); + let alias = Alias::new(account_name, domain_id.clone()); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + let account_id = AccountId::new(public_key, alias); let asset_id = AssetId::new( AssetDefinitionId::new(asset_name, domain_id.clone()), account_id.clone(), diff --git a/data_model/src/expression.rs b/data_model/src/expression.rs index 47b3b0b9cb1..4bbd82f799f 100644 --- a/data_model/src/expression.rs +++ b/data_model/src/expression.rs @@ -22,7 +22,10 @@ use operation::*; use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; -use super::{query::QueryBox, Value, ValueBox}; +use crate::{ + query::QueryBox, + value::Value, prelude::{Alias, FindAccountIdByAlias}, IdBox, +}; /// Generate expression structure and basic impls for it. /// @@ -255,6 +258,23 @@ impl EvaluatesTo { } } +impl From for ExpressionBox { + fn from(alias: Alias) -> Self { + Box::new(Expression::Query(QueryBox::FindAccountIdByAlias(FindAccountIdByAlias::new(alias)))) + } +} + +impl From for EvaluatesTo { + fn from(alias: Alias) -> Self { + let expression = alias.into(); + + Self { + expression, + _value_type: PhantomData, + } + } +} + impl> IntoSchema for EvaluatesTo { fn type_name() -> String { format!("{}::EvaluatesTo<{}>", module_path!(), V::type_name()) @@ -280,43 +300,43 @@ mod operation { //! Module containing operations and their priorities. /// Type of expression operation. - #[derive(Copy, Clone, PartialEq, Eq)] - pub enum Operation { - MethodCall, - RaiseTo, - Multiply, - Divide, - Mod, - Add, - Subtract, - Greater, - Less, - Equal, - Not, - And, - Or, - Other, - } + #[derive(Copy, Clone, PartialEq, Eq)] + pub enum Operation { + MethodCall, + RaiseTo, + Multiply, + Divide, + Mod, + Add, + Subtract, + Greater, + Less, + Equal, + Not, + And, + Or, + Other, + } - /// Priority of operation. - /// - /// [`First`](Operation::First) is the highest priority - /// and [`Ninth`](Operation::Ninth) is the lowest. - #[derive(Debug, Copy, Clone, PartialEq, Eq)] - pub enum Priority { - First = 1, - Second = 2, - Third = 3, - Fourth = 4, - Fifth = 5, - Sixth = 6, - Seventh = 7, - Eighth = 8, - Ninth = 9, - } + /// Priority of operation. + /// + /// [`First`](Operation::First) is the highest priority + /// and [`Ninth`](Operation::Ninth) is the lowest. + #[derive(Debug, Copy, Clone, PartialEq, Eq)] + pub enum Priority { + First = 1, + Second = 2, + Third = 3, + Fourth = 4, + Fifth = 5, + Sixth = 6, + Seventh = 7, + Eighth = 8, + Ninth = 9, + } - impl Operation { - /// Get the priority of the operation. + impl Operation { +/// Get the priority of the operation. /// /// Ordering is the same as in Python code. /// See [`here`](https://docs.python.org/3/reference/expressions.html#operator-precedence) @@ -405,7 +425,7 @@ pub enum Expression { /// If expression. If(If), /// Raw value. - Raw(ValueBox), + Raw(Box), /// Query to Iroha state. Query(QueryBox), /// Contains expression for vectors. @@ -430,83 +450,37 @@ impl Expression { Add(add) => add.len(), Subtract(subtract) => subtract.len(), Greater(greater) => greater.len(), - Less(less) => less.len(), - Equal(equal) => equal.len(), - Not(not) => not.len(), - And(and) => and.len(), - Or(or) => or.len(), - If(if_expression) => if_expression.len(), - Raw(raw) => raw.len(), - Query(query) => query.len(), - Contains(contains) => contains.len(), - ContainsAll(contains_all) => contains_all.len(), - ContainsAny(contains_any) => contains_any.len(), - Where(where_expression) => where_expression.len(), - ContextValue(context_value) => context_value.len(), - Multiply(multiply) => multiply.len(), - Divide(divide) => divide.len(), - Mod(modulus) => modulus.len(), - RaiseTo(raise_to) => raise_to.len(), + Less(less) => less.len(), + Equal(equal) => equal.len(), + Not(not) => not.len(), + And(and) => and.len(), + Or(or) => or.len(), + If(if_expression) => if_expression.len(), + Raw(raw) => raw.len(), + Query(query) => query.len(), + Contains(contains) => contains.len(), + ContainsAll(contains_all) => contains_all.len(), + ContainsAny(contains_any) => contains_any.len(), + Where(where_expression) => where_expression.len(), + ContextValue(context_value) => context_value.len(), + Multiply(multiply) => multiply.len(), + Divide(divide) => divide.len(), + Mod(modulus) => modulus.len(), + RaiseTo(raise_to) => raise_to.len(), + } } } -} - -impl> From for ExpressionBox { - fn from(value: T) -> Self { - Expression::Raw(Box::new(value.into())).into() - } -} - -/// Get a temporary value by name. -/// The values are brought into [`Context`] by [`Where`] expression. -// -// Can't use `gen_expr_and_impls!` here because we need special type for `value_name` -#[derive( - Debug, - Display, - Clone, - PartialEq, - Eq, - Decode, - Encode, - Deserialize, - Serialize, - IntoSchema, - PartialOrd, - Ord, -)] -#[display(fmt = "CONTEXT `{}`", value_name)] -pub struct ContextValue { - /// Name bound to the value. - pub value_name: String, -} - -impl ContextValue { - /// Number of underneath expressions. - #[inline] - pub const fn len(&self) -> usize { - 1 - } - /// Constructs `ContextValue`. - #[inline] - pub fn new(value_name: &str) -> Self { - Self { - value_name: String::from(value_name), + impl> From for ExpressionBox { + fn from(value: T) -> Self { + Expression::Raw(Box::new(value.into())).into() } } -} -impl From for ExpressionBox { - #[inline] - fn from(expression: ContextValue) -> Self { - Expression::ContextValue(expression).into() - } -} - -gen_expr_and_impls! { - /// Evaluates to the multiplication of left and right expressions. - /// Works only for [`Value::U32`] + /// Get a temporary value by name. + /// The values are brought into [`Context`] by [`Where`] expression. + // + // Can't use `gen_expr_and_impls!` here because we need special type for `value_name` #[derive( Debug, Display, @@ -521,6 +495,52 @@ gen_expr_and_impls! { PartialOrd, Ord, )] + #[display(fmt = "CONTEXT `{}`", value_name)] + pub struct ContextValue { + /// Name bound to the value. + pub value_name: String, + } + + impl ContextValue { + /// Number of underneath expressions. + #[inline] + pub const fn len(&self) -> usize { + 1 + } + + /// Constructs `ContextValue`. + #[inline] + pub fn new(value_name: &str) -> Self { + Self { + value_name: String::from(value_name), + } + } + } + + impl From for ExpressionBox { + #[inline] + fn from(expression: ContextValue) -> Self { + Expression::ContextValue(expression).into() + } + } + + gen_expr_and_impls! { + /// Evaluates to the multiplication of left and right expressions. + /// Works only for [`Value::U32`] + #[derive( + Debug, + Display, + Clone, + PartialEq, + Eq, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + PartialOrd, + Ord, + )] #[display( fmt = "{}*{}", // Keep without spaces "self.left.parenthesise(Operation::Multiply)", diff --git a/data_model/src/ipfs.rs b/data_model/src/ipfs.rs new file mode 100644 index 00000000000..8dc3c836e7e --- /dev/null +++ b/data_model/src/ipfs.rs @@ -0,0 +1,184 @@ +use crate::alloc; +use crate::ParseError; +use core::str::FromStr; +use iroha_ffi::{IntoFfi, TryFromReprC}; +use iroha_primitives::conststr::ConstString; +use iroha_schema::IntoSchema; +use parity_scale_codec::{Decode, Encode}; +use serde::{Deserialize, Serialize}; + +/// Represents path in IPFS. Performs checks to ensure path validity. +/// Construct using [`FromStr::from_str`] method. +#[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Encode, + Serialize, + IntoFfi, + TryFromReprC, + IntoSchema, +)] +pub struct IpfsPath(ConstString); + +impl FromStr for IpfsPath { + type Err = ParseError; + + fn from_str(string: &str) -> Result { + let mut subpath = string.split('/'); + let path_segment = subpath.next().ok_or(ParseError { + reason: "Impossible error: first value of str::split() always has value", + })?; + + if path_segment.is_empty() { + let root_type = subpath.next().ok_or(ParseError { + reason: "Expected root type, but nothing found", + })?; + let key = subpath.next().ok_or(ParseError { + reason: "Expected at least one content id", + })?; + + match root_type { + "ipfs" | "ipld" => Self::check_cid(key)?, + "ipns" => (), + _ => { + return Err(ParseError { + reason: "Unexpected root type. Expected `ipfs`, `ipld` or `ipns`", + }) + } + } + } else { + // by default if there is no prefix it's an ipfs or ipld path + Self::check_cid(path_segment)?; + } + + for path in subpath { + Self::check_cid(path)?; + } + + Ok(IpfsPath(ConstString::from(string))) + } +} + +impl AsRef for IpfsPath { + #[inline] + fn as_ref(&self) -> &str { + &self.0 + } +} + +impl IpfsPath { + /// Superficially checks IPFS `cid` (Content Identifier) + #[inline] + const fn check_cid(cid: &str) -> Result<(), ParseError> { + if cid.len() < 2 { + return Err(ParseError { + reason: "IPFS cid is too short", + }); + } + + Ok(()) + } +} + +impl<'de> Deserialize<'de> for IpfsPath { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[cfg(not(feature = "std"))] + use alloc::borrow::Cow; + #[cfg(feature = "std")] + use std::borrow::Cow; + + use serde::de::Error as _; + + let name = >::deserialize(deserializer)?; + Self::from_str(&name).map_err(D::Error::custom) + } +} + +impl Decode for IpfsPath { + fn decode( + input: &mut I, + ) -> Result { + let name = ConstString::decode(input)?; + Self::from_str(&name).map_err(|error| error.reason.into()) + } +} + +#[cfg(test)] +mod tests { + #![allow(clippy::restriction)] + + use super::*; + + const INVALID_IPFS: [&str; 4] = [ + "", + "/ipld", + "/ipfs/a", + "/ipfsssss/QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE", + ]; + + #[test] + fn test_invalid_ipfs_path() { + assert!(matches!( + IpfsPath::from_str(INVALID_IPFS[0]), + Err(err) if err.to_string() == "Expected root type, but nothing found" + )); + assert!(matches!( + IpfsPath::from_str(INVALID_IPFS[1]), + Err(err) if err.to_string() == "Expected at least one content id" + )); + assert!(matches!( + IpfsPath::from_str(INVALID_IPFS[2]), + Err(err) if err.to_string() == "IPFS cid is too short" + )); + assert!(matches!( + IpfsPath::from_str(INVALID_IPFS[3]), + Err(err) if err.to_string() == "Unexpected root type. Expected `ipfs`, `ipld` or `ipns`" + )); + } + + #[test] + #[allow(clippy::expect_used)] + fn test_valid_ipfs_path() { + // Valid paths + IpfsPath::from_str("QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE") + .expect("Path without root should be valid"); + IpfsPath::from_str("/ipfs/QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE") + .expect("Path with ipfs root should be valid"); + IpfsPath::from_str("/ipld/QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE") + .expect("Path with ipld root should be valid"); + IpfsPath::from_str("/ipns/QmSrPmbaUKA3ZodhzPWZnpFgcPMFWF4QsxXbkWfEptTBJd") + .expect("Path with ipns root should be valid"); + IpfsPath::from_str("/ipfs/SomeFolder/SomeImage") + .expect("Path with folders should be valid"); + } + + #[test] + fn deserialize_ipfs() { + for invalid_ipfs in INVALID_IPFS { + let invalid_ipfs = IpfsPath(invalid_ipfs.into()); + let serialized = serde_json::to_string(&invalid_ipfs).expect("Valid"); + let ipfs = serde_json::from_str::(serialized.as_str()); + + assert!(ipfs.is_err()); + } + } + + #[test] + fn decode_ipfs() { + for invalid_ipfs in INVALID_IPFS { + let invalid_ipfs = IpfsPath(invalid_ipfs.into()); + let bytes = invalid_ipfs.encode(); + let ipfs = IpfsPath::decode(&mut &bytes[..]); + + assert!(ipfs.is_err()); + } + } +} diff --git a/data_model/src/isi.rs b/data_model/src/isi.rs index d313accf125..fe1f2b271e0 100644 --- a/data_model/src/isi.rs +++ b/data_model/src/isi.rs @@ -12,8 +12,8 @@ use iroha_schema::IntoSchema; use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; -use super::{expression::EvaluatesTo, prelude::*, IdBox, RegistrableBox, Value}; use crate::Registered; +use crate::{expression::EvaluatesTo, prelude::*, value::Value, IdBox, RegistrableBox}; /// Sized structure for all possible Instructions. #[derive( @@ -98,7 +98,7 @@ pub struct SetKeyValueBox { pub value: EvaluatesTo, } -/// Sized structure for all possible key value pair remove instructions. +/// Sized structure for all possible key value pair remove instructions.g #[derive( Debug, Display, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema, )] diff --git a/data_model/src/lib.rs b/data_model/src/lib.rs index 1aa92021104..0568560d89b 100644 --- a/data_model/src/lib.rs +++ b/data_model/src/lib.rs @@ -1,9 +1,7 @@ //! Iroha Data Model contains structures for Domains, Peers, Accounts and Assets with simple, //! non-specific functions like serialization. - #![allow( clippy::module_name_repetitions, - clippy::unwrap_in_result, clippy::std_instead_of_alloc, clippy::arithmetic, clippy::trait_duplication_in_bounds @@ -22,14 +20,14 @@ use alloc::{ string::{String, ToString}, vec::Vec, }; +use value::Value; use core::{convert::AsRef, fmt, fmt::Debug, ops::RangeInclusive}; #[cfg(feature = "std")] use std::alloc::alloc; use block_value::{BlockHeaderValue, BlockValue}; -#[cfg(not(target_arch = "aarch64"))] -use derive_more::Into; -use derive_more::{AsRef, Deref, Display, From}; + +use derive_more::Display; use events::FilterBox; use iroha_crypto::{Hash, PublicKey}; use iroha_ffi::{IntoFfi, TryFromReprC}; @@ -38,7 +36,7 @@ use iroha_primitives::{ fixed, small::{Array as SmallArray, SmallVec}, }; -use iroha_schema::{IntoSchema, MetaMap}; +use iroha_schema::IntoSchema; use parity_scale_codec::{Decode, Encode}; use prelude::TransactionQueryResult; use serde::{Deserialize, Serialize}; @@ -54,6 +52,7 @@ pub mod block_value; pub mod domain; pub mod events; pub mod expression; +pub mod ipfs; pub mod isi; pub mod metadata; pub mod name; @@ -66,6 +65,7 @@ pub mod role; pub mod sorting; pub mod transaction; pub mod trigger; +pub mod value; pub mod utils { #![allow(clippy::doc_link_with_quotes)] @@ -430,215 +430,6 @@ impl<'idbox> TryFrom<&'idbox IdentifiableBox> for &'idbox dyn HasMetadata { } } -/// Create a [`Vec`] containing the arguments, which should satisfy `Into` bound. -/// -/// Syntax is the same as in [`vec`](macro@vec) -#[macro_export] -macro_rules! val_vec { - () => { Vec::new() }; - ($elem:expr; $n:expr) => { vec![iroha_data_model::Value::from($elem); $n] }; - ($($x:expr),+ $(,)?) => { vec![$(iroha_data_model::Value::from($x),)+] }; -} - -/// Boxed [`Value`]. -pub type ValueBox = Box; - -/// Sized container for all possible values. -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Decode, - Encode, - Deserialize, - Serialize, - FromVariant, - IntoFfi, - TryFromReprC, - IntoSchema, -)] -#[allow(clippy::enum_variant_names)] -#[repr(u8)] -pub enum Value { - /// [`u32`] integer. - U32(u32), - /// [`u128`] integer. - U128(u128), - /// [`bool`] value. - Bool(bool), - /// [`String`] value. - String(String), - /// [`Name`] value. - Name(Name), - /// [`fixed::Fixed`] value - Fixed(fixed::Fixed), - /// [`Vec`] of `Value`. - Vec( - #[skip_from] - #[skip_try_from] - Vec, - ), - /// Recursive inclusion of LimitedMetadata, - LimitedMetadata(metadata::Metadata), - /// `Id` of `Asset`, `Account`, etc. - Id(IdBox), - /// `impl Identifiable` as in `Asset`, `Account` etc. - Identifiable(IdentifiableBox), - /// [`PublicKey`]. - PublicKey(PublicKey), - /// Iroha [`Parameter`] variant. - Parameter(Parameter), - /// Signature check condition. - SignatureCheckCondition(SignatureCheckCondition), - /// Committed or rejected transactions - TransactionValue(TransactionValue), - /// Transaction Query - TransactionQueryResult(TransactionQueryResult), - /// [`PermissionToken`]. - PermissionToken(PermissionToken), - /// [`struct@Hash`] - Hash(Hash), - /// Block - Block(BlockValueWrapper), - /// Block headers - BlockHeader(BlockHeaderValue), -} - -/// Cross-platform wrapper for `BlockValue`. -#[cfg(not(target_arch = "aarch64"))] -#[derive( - AsRef, - Clone, - Debug, - Decode, - Deref, - Deserialize, - Encode, - Eq, - From, - Into, - Ord, - PartialEq, - PartialOrd, - Serialize, -)] -#[serde(transparent)] -pub struct BlockValueWrapper(BlockValue); - -/// Cross-platform wrapper for `BlockValue`. -#[cfg(target_arch = "aarch64")] -#[derive( - AsRef, - Clone, - Debug, - Decode, - Deref, - Deserialize, - Encode, - Eq, - From, - Ord, - PartialEq, - PartialOrd, - Serialize, -)] -#[as_ref(forward)] -#[deref(forward)] -#[from(forward)] -#[serde(transparent)] -pub struct BlockValueWrapper(Box); - -#[cfg(target_arch = "aarch64")] -impl From for BlockValue { - fn from(block_value: BlockValueWrapper) -> Self { - *block_value.0 - } -} - -impl IntoSchema for BlockValueWrapper { - fn type_name() -> String { - BlockValue::type_name() - } - - fn schema(map: &mut MetaMap) { - BlockValue::schema(map); - } -} - -impl fmt::Display for Value { - // TODO: Maybe derive - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Value::U32(v) => fmt::Display::fmt(&v, f), - Value::U128(v) => fmt::Display::fmt(&v, f), - Value::Bool(v) => fmt::Display::fmt(&v, f), - Value::String(v) => fmt::Display::fmt(&v, f), - Value::Name(v) => fmt::Display::fmt(&v, f), - Value::Fixed(v) => fmt::Display::fmt(&v, f), - #[allow(clippy::use_debug)] - Value::Vec(v) => { - // TODO: Remove so we can derive. - let list_of_display: Vec<_> = v.iter().map(ToString::to_string).collect(); - // this prints with quotation marks, which is fine 90% - // of the time, and helps delineate where a display of - // one value stops and another one begins. - write!(f, "{:?}", list_of_display) - } - Value::LimitedMetadata(v) => fmt::Display::fmt(&v, f), - Value::Id(v) => fmt::Display::fmt(&v, f), - Value::Identifiable(v) => fmt::Display::fmt(&v, f), - Value::PublicKey(v) => fmt::Display::fmt(&v, f), - Value::Parameter(v) => fmt::Display::fmt(&v, f), - Value::SignatureCheckCondition(v) => fmt::Display::fmt(&v, f), - Value::TransactionValue(_) => write!(f, "TransactionValue"), - Value::TransactionQueryResult(_) => write!(f, "TransactionQueryResult"), - Value::PermissionToken(v) => fmt::Display::fmt(&v, f), - Value::Hash(v) => fmt::Display::fmt(&v, f), - Value::Block(v) => fmt::Display::fmt(&**v, f), - Value::BlockHeader(v) => fmt::Display::fmt(&v, f), - } - } -} - -#[allow(clippy::len_without_is_empty)] -impl Value { - /// Number of underneath expressions. - pub fn len(&self) -> usize { - use Value::*; - - match self { - U32(_) - | U128(_) - | Id(_) - | PublicKey(_) - | Bool(_) - | Parameter(_) - | Identifiable(_) - | String(_) - | Name(_) - | Fixed(_) - | TransactionValue(_) - | TransactionQueryResult(_) - | PermissionToken(_) - | Hash(_) - | Block(_) - | BlockHeader(_) => 1_usize, - Vec(v) => v.iter().map(Self::len).sum::() + 1_usize, - LimitedMetadata(data) => data.nested_len() + 1_usize, - SignatureCheckCondition(s) => s.0.len(), - } - } -} - -impl From for Value { - fn from(block_value: BlockValue) -> Self { - Value::Block(block_value.into()) - } -} - impl From> for Value where A::Item: Into, @@ -658,11 +449,11 @@ where macro_rules! from_and_try_from_value_idbox { ( $($variant:ident( $ty:ty ),)* $(,)? ) => { $( - impl TryFrom for $ty { - type Error = ErrorTryFromEnum; + impl TryFrom<$crate::value::Value> for $ty { + type Error = ErrorTryFromEnum; fn try_from(value: Value) -> Result { - if let Value::Id(IdBox::$variant(id)) = value { + if let $crate::value::Value::Id(IdBox::$variant(id)) = value { Ok(id) } else { Err(Self::Error::default()) @@ -670,9 +461,9 @@ macro_rules! from_and_try_from_value_idbox { } } - impl From<$ty> for Value { + impl From<$ty> for $crate::value::Value { fn from(id: $ty) -> Self { - Value::Id(IdBox::$variant(id)) + $crate::value::Value::Id(IdBox::$variant(id)) } } )* @@ -682,7 +473,7 @@ macro_rules! from_and_try_from_value_idbox { from_and_try_from_value_idbox!( PeerId(peer::Id), DomainId(domain::Id), - AccountId(account::Id), + AccountId(::Id), AssetId(asset::Id), AssetDefinitionId(asset::DefinitionId), TriggerId(trigger::Id), @@ -1055,10 +846,11 @@ pub mod prelude { name::prelude::*, pagination::prelude::*, peer::prelude::*, role::prelude::*, sorting::prelude::*, trigger::prelude::*, EnumTryAsError, HasMetadata, IdBox, Identifiable, IdentifiableBox, Parameter, PredicateTrait, RegistrableBox, TryAsMut, TryAsRef, - ValidationError, Value, + ValidationError, }; pub use crate::{ events::prelude::*, expression::prelude::*, isi::prelude::*, metadata::prelude::*, permissions::prelude::*, query::prelude::*, transaction::prelude::*, trigger::prelude::*, + value::prelude::*, }; } diff --git a/data_model/src/metadata.rs b/data_model/src/metadata.rs index fa412800b35..85b303c9bd4 100644 --- a/data_model/src/metadata.rs +++ b/data_model/src/metadata.rs @@ -13,7 +13,7 @@ use iroha_schema::IntoSchema; use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; -use crate::{Name, Value}; +use crate::{Name, value::Value}; /// Collection of parameters by their names. pub type UnlimitedMetadata = btree_map::BTreeMap; diff --git a/data_model/src/peer.rs b/data_model/src/peer.rs index 8df1c129b2d..f6fe4e91738 100644 --- a/data_model/src/peer.rs +++ b/data_model/src/peer.rs @@ -13,7 +13,7 @@ use iroha_schema::IntoSchema; use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; -use crate::{Identifiable, PublicKey, Registered, Value}; +use crate::{Identifiable, PublicKey, Registered, value::Value}; /// Peer represents Iroha instance. #[derive( diff --git a/data_model/src/permissions.rs b/data_model/src/permissions.rs index aaae93a2fa4..fc101867d67 100644 --- a/data_model/src/permissions.rs +++ b/data_model/src/permissions.rs @@ -23,7 +23,7 @@ use iroha_schema::IntoSchema; use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; -use crate::{ffi::ffi_item, utils::format_comma_separated, Identifiable, Name, Registered, Value}; +use crate::{ffi::ffi_item, utils::format_comma_separated, Identifiable, Name, Registered, value::Value}; /// Collection of [`PermissionToken`]s pub type Permissions = btree_set::BTreeSet; diff --git a/data_model/src/predicate.rs b/data_model/src/predicate.rs index 19133b42276..a745e785ae3 100644 --- a/data_model/src/predicate.rs +++ b/data_model/src/predicate.rs @@ -222,6 +222,7 @@ pub mod string { mod id_box { use super::*; + use iroha_crypto::KeyPair; #[test] fn simple_name_wrappers() { @@ -295,7 +296,9 @@ pub mod string { #[test] fn account_id() { - let id = IdBox::AccountId("alice@wonderland".parse().expect("Valid")); + let alias = "alice@wonderland".parse().expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + let id = IdBox::AccountId(crate::account::Id::new(public_key, alias)); assert!(Predicate::starts_with("alice@").applies(&id)); assert!(Predicate::ends_with("@wonderland").applies(&id)); assert!(Predicate::is("alice@wonderland").applies(&id)); @@ -314,7 +317,10 @@ pub mod string { #[test] fn asset_id() { let definition_id = "rose#wonderland".parse().expect("Valid"); - let account_id = "alice@wonderland".parse().expect("Valid"); + let alias = "alice@wonderland".parse().expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + let account_id = crate::account::Id::new(public_key, alias); + let _id = IdBox::AccountId(account_id.clone()); let id = IdBox::AssetId(crate::asset::Id { definition_id, account_id, @@ -764,11 +770,14 @@ pub mod value { #[cfg(test)] #[allow(clippy::print_stdout, clippy::use_debug, clippy::expect_used)] mod test { + use account::Alias; + use core::str::FromStr as _; + use iroha_crypto::KeyPair; use peer::Peer; use prelude::Metadata; use super::*; - use crate::account::Account; + use crate::account::{Account, Id as AccountId}; #[test] fn typing() { @@ -776,9 +785,12 @@ pub mod value { let pred = Predicate::Identifiable(string::Predicate::is("alice@wonderland")); println!("{pred:?}"); assert!(pred.applies(&Value::String("alice@wonderland".to_owned()))); - assert!(pred.applies(&Value::Id(IdBox::AccountId( - "alice@wonderland".parse().expect("Valid") - )))); + let account_id = { + let alias = Alias::from_str("alice@wonderland").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + assert!(pred.applies(&Value::Id(IdBox::AccountId(account_id)))); assert!( pred.applies(&Value::Identifiable(IdentifiableBox::NewAccount(Box::new( Account::new("alice@wonderland".parse().expect("Valid"), []) diff --git a/data_model/src/query.rs b/data_model/src/query.rs index 865573a4fcb..6665f97dcfa 100644 --- a/data_model/src/query.rs +++ b/data_model/src/query.rs @@ -18,7 +18,7 @@ use self::{ trigger::*, }; use crate::{ - account::Account, pagination::Pagination, predicate::PredicateBox, Identifiable, Value, + account::Account, pagination::Pagination, predicate::PredicateBox, Identifiable, value::Value, }; /// Sized container for all possible Queries. @@ -43,6 +43,8 @@ pub enum QueryBox { FindAllAccounts(FindAllAccounts), /// [`FindAccountById`] variant. FindAccountById(FindAccountById), + /// [`FindAccountIdByAlias`] variant. + FindAccountIdByAlias(FindAccountIdByAlias), /// [`FindAccountKeyValueByIdAndKey`] variant. FindAccountKeyValueByIdAndKey(FindAccountKeyValueByIdAndKey), /// [`FindAccountsByName`] variant. @@ -507,6 +509,33 @@ pub mod account { type Output = Account; } + /// [`FindAccountById`] Iroha Query finds an [`Account`] by it's identification. + #[derive( + Debug, + Display, + Clone, + PartialEq, + Eq, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + PartialOrd, + Ord, + )] + #[display(fmt = "Find `{}` account", alias)] + pub struct FindAccountIdByAlias { + /// `Id` of an account to find. + pub alias: EvaluatesTo, + } + + impl Query for FindAccountIdByAlias { + type Output = AccountId; + } + + + /// [`FindAccountKeyValueByIdAndKey`] Iroha Query finds a [`Value`] /// of the key-value metadata pair in the specified account. #[derive( @@ -616,7 +645,7 @@ pub mod account { impl FindAllAccounts { /// Construct [`FindAllAccounts`]. pub const fn new() -> Self { - FindAllAccounts + Self } } @@ -624,10 +653,17 @@ pub mod account { /// Construct [`FindAccountById`]. pub fn new(id: impl Into>) -> Self { let id = id.into(); - FindAccountById { id } + Self { id } } } + impl FindAccountIdByAlias { + pub fn new(id: impl Into>) -> Self { + let alias = id.into(); + Self { alias } + } + } + impl FindAccountKeyValueByIdAndKey { /// Construct [`FindAccountById`]. pub fn new( @@ -644,7 +680,7 @@ pub mod account { /// Construct [`FindAccountsByName`]. pub fn new(name: impl Into>) -> Self { let name = name.into(); - FindAccountsByName { name } + Self { name } } } @@ -652,7 +688,7 @@ pub mod account { /// Construct [`FindAccountsByDomainId`]. pub fn new(domain_id: impl Into>) -> Self { let domain_id = domain_id.into(); - FindAccountsByDomainId { domain_id } + Self { domain_id } } } @@ -660,7 +696,7 @@ pub mod account { /// Construct [`FindAccountsWithAsset`]. pub fn new(asset_definition_id: impl Into>) -> Self { let asset_definition_id = asset_definition_id.into(); - FindAccountsWithAsset { + Self { asset_definition_id, } } @@ -670,7 +706,7 @@ pub mod account { pub mod prelude { pub use super::{ FindAccountById, FindAccountKeyValueByIdAndKey, FindAccountsByDomainId, - FindAccountsByName, FindAccountsWithAsset, FindAllAccounts, + FindAccountsByName, FindAccountsWithAsset, FindAllAccounts, FindAccountIdByAlias }; } } @@ -1351,7 +1387,7 @@ pub mod trigger { use super::Query; use crate::{ domain::prelude::*, events::FilterBox, expression::EvaluatesTo, trigger::Trigger, - Identifiable, Name, Value, + Identifiable, Name, value::Value, }; /// Find all currently active (as in not disabled and/or expired) diff --git a/data_model/src/trigger/mod.rs b/data_model/src/trigger/mod.rs index 5f7ba5adf98..f034c171ced 100644 --- a/data_model/src/trigger/mod.rs +++ b/data_model/src/trigger/mod.rs @@ -218,7 +218,7 @@ pub mod action { use iroha_primitives::atomic::AtomicU32; use super::*; - use crate::HasMetadata; + use crate::{prelude::Account, HasMetadata}; /// Trait for common methods for all [`Action`]'s pub trait ActionTrait { @@ -232,7 +232,7 @@ pub mod action { fn set_repeats(&mut self, repeats: Repeats); /// Get action technical account - fn technical_account(&self) -> &crate::account::Id; + fn technical_account(&self) -> &::Id; /// Get action metadata fn metadata(&self) -> &Metadata; @@ -270,7 +270,7 @@ pub mod action { /// Technical account linked to this trigger. The technical /// account must already exist in order for `Register` to /// work. - pub technical_account: crate::account::Id, + pub technical_account: ::Id, /// Defines events which trigger the `Action` pub filter: F, /// Metadata used as persistent storage for trigger data. @@ -288,7 +288,7 @@ pub mod action { pub fn new( executable: impl Into, repeats: impl Into, - technical_account: crate::account::Id, + technical_account: ::Id, filter: F, ) -> Self { Self { @@ -322,7 +322,7 @@ pub mod action { self.repeats = repeats; } - fn technical_account(&self) -> &crate::account::Id { + fn technical_account(&self) -> &::Id { &self.technical_account } diff --git a/data_model/src/value.rs b/data_model/src/value.rs new file mode 100644 index 00000000000..14b5163ec58 --- /dev/null +++ b/data_model/src/value.rs @@ -0,0 +1,145 @@ +//! The Value-oriented logic. +use super::*; + +/// Create a [`Vec`] containing the arguments, which should satisfy `Into` bound. +/// +/// Syntax is the same as in [`vec`](macro@vec) +#[macro_export] +macro_rules! val_vec { + () => { Vec::new() }; + ($elem:expr; $n:expr) => { vec![$crate::value::Value::from($elem); $n] }; + ($($x:expr),+ $(,)?) => { vec![$($crate::value::Value::from($x),)+] }; +} + +/// Sized container for all possible values. +#[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + FromVariant, + IntoFfi, + TryFromReprC, + IntoSchema, +)] +#[allow(clippy::enum_variant_names)] +#[repr(u8)] +pub enum Value { + /// [`u32`] integer. + U32(u32), + /// [`u128`] integer. + U128(u128), + /// [`bool`] value. + Bool(bool), + /// [`String`] value. + String(String), + /// [`Name`] value. + Name(Name), + /// [`fixed::Fixed`] value + Fixed(fixed::Fixed), + /// [`Vec`] of `Value`. + Vec( + #[skip_from] + #[skip_try_from] + Vec, + ), + /// Recursive inclusion of LimitedMetadata, + LimitedMetadata(metadata::Metadata), + /// `Id` of `Asset`, `Account`, etc. + Id(IdBox), + /// `impl Identifiable` as in `Asset`, `Account` etc. + Identifiable(IdentifiableBox), + /// [`PublicKey`]. + PublicKey(PublicKey), + /// Iroha [`Parameter`] variant. + Parameter(Parameter), + /// Signature check condition. + SignatureCheckCondition(SignatureCheckCondition), + /// Committed or rejected transactions + TransactionValue(TransactionValue), + /// Transaction Query + TransactionQueryResult(TransactionQueryResult), + /// [`PermissionToken`]. + PermissionToken(PermissionToken), + /// [`struct@Hash`] + Hash(Hash), + /// Block + Block(block_value::BlockValueWrapper), + /// Block headers + BlockHeader(BlockHeaderValue), +} + +#[allow(clippy::len_without_is_empty)] +impl Value { + /// Number of underneath expressions. + pub fn len(&self) -> usize { + use Value::*; + + match self { + U32(_) + | U128(_) + | Id(_) + | PublicKey(_) + | Bool(_) + | Parameter(_) + | Identifiable(_) + | String(_) + | Name(_) + | Fixed(_) + | TransactionValue(_) + | TransactionQueryResult(_) + | PermissionToken(_) + | Hash(_) + | Block(_) + | BlockHeader(_) => 1_usize, + Vec(v) => v.iter().map(Self::len).sum::() + 1_usize, + LimitedMetadata(data) => data.nested_len() + 1_usize, + SignatureCheckCondition(s) => s.0.len(), + } + } +} + +impl fmt::Display for Value { + // TODO: Maybe derive + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Value::U32(v) => fmt::Display::fmt(&v, f), + Value::U128(v) => fmt::Display::fmt(&v, f), + Value::Bool(v) => fmt::Display::fmt(&v, f), + Value::String(v) => fmt::Display::fmt(&v, f), + Value::Name(v) => fmt::Display::fmt(&v, f), + Value::Fixed(v) => fmt::Display::fmt(&v, f), + #[allow(clippy::use_debug)] + Value::Vec(v) => { + // TODO: Remove so we can derive. + let list_of_display: Vec<_> = v.iter().map(ToString::to_string).collect(); + // this prints with quotation marks, which is fine 90% + // of the time, and helps delineate where a display of + // one value stops and another one begins. + write!(f, "{:?}", list_of_display) + } + Value::LimitedMetadata(v) => fmt::Display::fmt(&v, f), + Value::Id(v) => fmt::Display::fmt(&v, f), + Value::Identifiable(v) => fmt::Display::fmt(&v, f), + Value::PublicKey(v) => fmt::Display::fmt(&v, f), + Value::Parameter(v) => fmt::Display::fmt(&v, f), + Value::SignatureCheckCondition(v) => fmt::Display::fmt(&v, f), + Value::TransactionValue(_) => write!(f, "TransactionValue"), + Value::TransactionQueryResult(_) => write!(f, "TransactionQueryResult"), + Value::PermissionToken(v) => fmt::Display::fmt(&v, f), + Value::Hash(v) => fmt::Display::fmt(&v, f), + Value::Block(v) => fmt::Display::fmt(&**v, f), + Value::BlockHeader(v) => fmt::Display::fmt(&v, f), + } + } +} + +pub mod prelude { + pub use super::Value; +} diff --git a/data_model/tests/data_model.rs b/data_model/tests/data_model.rs index 9e8db7c2666..96123d282fe 100644 --- a/data_model/tests/data_model.rs +++ b/data_model/tests/data_model.rs @@ -12,6 +12,7 @@ use iroha_data_model::{prelude::*, ParseError}; use iroha_primitives::small::SmallStr; use test_network::{prepare_test_for_nextest, Peer as TestPeer, PeerBuilder, TestRuntime}; use tokio::runtime::Runtime; +use test_network::FreshKeyTrait as _; fn asset_id_new( definition_name: &str, @@ -111,9 +112,9 @@ impl FindRateAndCheckItGreaterThanValue { format!("{}2{}_rate#exchange", self.from_currency, self.to_currency) .parse() .expect("Valid"), - AccountId::from_str("dex@exchange").expect("Valid"), + Alias::from_str("dex@exchange").expect("Valid").fresh_key(), ))) - .into(), + .into(), ), self.value, )), @@ -122,6 +123,7 @@ impl FindRateAndCheckItGreaterThanValue { } } + #[test] fn find_rate_and_check_it_greater_than_value_predefined_isi_should_be_valid() { let _instruction = FindRateAndCheckItGreaterThanValue::new("btc", "eth", 10).into_isi(); @@ -135,12 +137,13 @@ mod register { } pub fn account(account_name: &str, domain_name: &str) -> RegisterBox { + let public_key = KeyPair::generate().expect("Valid").public_key().clone(); RegisterBox::new(Account::new( - AccountId::new( + Alias::new( account_name.parse().expect("Valid"), domain_name.parse().expect("Valid"), ), - [], + [public_key], )) } diff --git a/permissions_validators/src/private_blockchain/query.rs b/permissions_validators/src/private_blockchain/query.rs index deb205ca2db..41d58cb1021 100644 --- a/permissions_validators/src/private_blockchain/query.rs +++ b/permissions_validators/src/private_blockchain/query.rs @@ -24,260 +24,263 @@ impl IsAllowed for OnlyAccountsDomain { wsv: &WorldStateView, ) -> ValidatorVerdict { use QueryBox::*; - match query { - FindAssetsByAssetDefinitionId(_) | FindAssetsByName(_) | FindAllAssets(_) => { - Deny("Only access to the assets of the same domain is permitted.".to_owned()) - } - FindAllAccounts(_) | FindAccountsByName(_) | FindAccountsWithAsset(_) => { - Deny("Only access to the accounts of the same domain is permitted.".to_owned()) - } - FindAllAssetsDefinitions(_) => Deny( - "Only access to the asset definitions of the same domain is permitted.".to_owned(), - ), - FindAllDomains(_) => { - Deny("Only access to the domain of the account is permitted.".to_owned()) - } - FindAllRoles(_) => { - Deny("Only access to roles of the same domain is permitted.".to_owned()) - } - FindAllRoleIds(_) => Allow, // In case you need to debug the permissions. - FindAllPermissionTokenDefinitions(_) => Allow, // Same - FindRoleByRoleId(_) => { - Deny("Only access to roles of the same domain is permitted.".to_owned()) - } - FindAllPeers(_) => Allow, // Can be obtained in other ways, so why hide it. - FindAllActiveTriggerIds(_) => Allow, - // Private blockchains should have debugging too, hence - // all accounts should also be - FindTriggerById(query) => { - let id = try_evaluate_or_deny!(query.id, wsv); - wsv.triggers() - .inspect_by_id(&id, |action| { - if action.technical_account() == authority { - Allow - } else { - Deny("Only technical accounts can access triggers.".to_owned()) - } - }) - .unwrap_or_else(|| { - Deny(format!( - "A trigger with the specified Id: {} is not accessible to you", - id.clone() - )) - }) - } - FindTriggerKeyValueByIdAndKey(query) => { - let id = try_evaluate_or_deny!(query.id, wsv); - wsv.triggers() - .inspect_by_id(&id, |action| { - if action.technical_account() == authority { - Allow - } else { - Deny( - "Only technical accounts can access the internal state of a Trigger." - .to_owned() - ) - } - }) - .unwrap_or_else(|| { - Deny( - format!( - "A trigger with the specified Id: {} is not accessible to you", - id.clone() - ), - ) - }) - } - FindTriggersByDomainId(query) => { - let domain_id = try_evaluate_or_deny!(query.domain_id, wsv); + todo!() + // if let Some(authority_domain) = authority.domain_id() { + // match query { + // FindAssetsByAssetDefinitionId(_) | FindAssetsByName(_) | FindAllAssets(_) => { + // Deny("Only access to the assets of the same domain is permitted.".to_owned()) + // } + // FindAllAccounts(_) | FindAccountsByName(_) | FindAccountsWithAsset(_) => { + // Deny("Only access to the accounts of the same domain is permitted.".to_owned()) + // } + // FindAllAssetsDefinitions(_) => Deny( + // "Only access to the asset definitions of the same domain is permitted.".to_owned(), + // ), + // FindAllDomains(_) => { + // Deny("Only access to the domain of the account is permitted.".to_owned()) + // } + // FindAllRoles(_) => { + // Deny("Only access to roles of the same domain is permitted.".to_owned()) + // } + // FindAllRoleIds(_) => Allow, // In case you need to debug the permissions. + // FindAllPermissionTokenDefinitions(_) => Allow, // Same + // FindRoleByRoleId(_) => { + // Deny("Only access to roles of the same domain is permitted.".to_owned()) + // } + // FindAllPeers(_) => Allow, // Can be obtained in other ways, so why hide it. + // FindAllActiveTriggerIds(_) => Allow, + // // Private blockchains should have debugging too, hence + // // all accounts should also be + // FindTriggerById(query) => { + // let id = try_evaluate_or_deny!(query.id, wsv); + // wsv.triggers() + // .inspect_by_id(&id, |action| { + // if action.technical_account() == authority { + // Allow + // } else { + // Deny("Only technical accounts can access triggers.".to_owned()) + // } + // }) + // .unwrap_or_else(|| { + // Deny(format!( + // "A trigger with the specified Id: {} is not accessible to you", + // id.clone() + // )) + // }) + // } + // FindTriggerKeyValueByIdAndKey(query) => { + // let id = try_evaluate_or_deny!(query.id, wsv); + // wsv.triggers() + // .inspect_by_id(&id, |action| { + // if action.technical_account() == authority { + // Allow + // } else { + // Deny( + // "Only technical accounts can access the internal state of a Trigger." + // .to_owned() + // ) + // } + // }) + // .unwrap_or_else(|| { + // Deny( + // format!( + // "A trigger with the specified Id: {} is not accessible to you", + // id.clone() + // ), + // ) + // }) + // } + // FindTriggersByDomainId(query) => { + // let domain_id = try_evaluate_or_deny!(query.domain_id, wsv); - if domain_id == authority.domain_id { - return Allow; - } + // if domain_id == *authority_domain { + // return Allow; + // } - Deny(format!( - "Cannot access triggers with given domain {}, {} is permitted..", - domain_id, authority.domain_id - )) - } - FindAccountById(query) => { - let account_id = try_evaluate_or_deny!(query.id, wsv); - if account_id.domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access account {} as it is in a different domain.", - account_id - )) - } - } - FindAccountKeyValueByIdAndKey(query) => { - let account_id = try_evaluate_or_deny!(query.id, wsv); - if account_id.domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access account {} as it is in a different domain.", - account_id - )) - } - } - FindAccountsByDomainId(query) => { - let domain_id = try_evaluate_or_deny!(query.domain_id, wsv); - if domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access accounts from a different domain with name {}.", - domain_id - )) - } - } - FindAssetById(query) => { - let asset_id = try_evaluate_or_deny!(query.id, wsv); - if asset_id.account_id.domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access asset {} as it is in a different domain.", - asset_id - )) - } - } - FindAssetsByAccountId(query) => { - let account_id = try_evaluate_or_deny!(query.account_id, wsv); - if account_id.domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access account {} as it is in a different domain.", - account_id - )) - } - } - FindAssetsByDomainId(query) => { - let domain_id = try_evaluate_or_deny!(query.domain_id, wsv); - if domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access assets from a different domain with name {}.", - domain_id - )) - } - } - FindAssetsByDomainIdAndAssetDefinitionId(query) => { - let domain_id = try_evaluate_or_deny!(query.domain_id, wsv); - if domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access assets from a different domain with name {}.", - domain_id - )) - } - } - FindAssetDefinitionKeyValueByIdAndKey(query) => { - let asset_definition_id = try_evaluate_or_deny!(query.id, wsv); - if asset_definition_id.domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access asset definition from a different domain. Asset definition domain: {}. Signer's account domain {}.", - asset_definition_id.domain_id, - authority.domain_id - )) - } - } - FindAssetQuantityById(query) => { - let asset_id = try_evaluate_or_deny!(query.id, wsv); - if asset_id.account_id.domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access asset {} as it is in a different domain.", - asset_id - )) - } - } - FindAssetKeyValueByIdAndKey(query) => { - let asset_id = try_evaluate_or_deny!(query.id, wsv); - if asset_id.account_id.domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access asset {} as it is in a different domain.", - asset_id - )) - } - } - FindDomainById(query::FindDomainById { id }) - | FindDomainKeyValueByIdAndKey(query::FindDomainKeyValueByIdAndKey { id, .. }) => { - let domain_id = try_evaluate_or_deny!(id, wsv); - if domain_id == authority.domain_id { - Allow - } else { - Deny(format!("Cannot access a different domain: {}.", domain_id)) - } - } - FindAllBlocks(_) => Deny("You are not permitted to access all blocks.".to_owned()), - FindAllBlockHeaders(_) => { - Deny("You are not permitted to access all blocks.".to_owned()) - } - FindBlockHeaderByHash(_) => { - Deny("You are not permitted to access arbitrary blocks.".to_owned()) - } - FindAllTransactions(_) => { - Deny("Cannot access transactions of another domain.".to_owned()) - } - FindTransactionsByAccountId(query) => { - let account_id = try_evaluate_or_deny!(query.account_id, wsv); - if account_id.domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access account {} as it is in a different domain.", - account_id - )) - } - } - FindTransactionByHash(_query) => Allow, - FindRolesByAccountId(query) => { - let account_id = try_evaluate_or_deny!(query.id, wsv); - if account_id.domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access account {} as it is in a different domain.", - account_id - )) - } - } - FindPermissionTokensByAccountId(query) => { - let account_id = try_evaluate_or_deny!(query.id, wsv); - if account_id.domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access account {} as it is in a different domain.", - account_id - )) - } - } - FindAssetDefinitionById(query) => { - let asset_definition_id = try_evaluate_or_deny!(query.id, wsv); + // Deny(format!( + // "Cannot access triggers with given domain {}, {} is permitted..", + // domain_id, authority_domain + // )) + // } + // FindAccountById(query) => { + // let account_id = try_evaluate_or_deny!(query.id, wsv); + // if account_id.domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access account {} as it is in a different domain.", + // account_id + // )) + // } + // } + // FindAccountKeyValueByIdAndKey(query) => { + // let account_id = try_evaluate_or_deny!(query.id, wsv); + // if account_id.domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access account {} as it is in a different domain.", + // account_id + // )) + // } + // } + // FindAccountsByDomainId(query) => { + // let domain_id = try_evaluate_or_deny!(query.domain_id, wsv); + // if domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access accounts from a different domain with name {}.", + // domain_id + // )) + // } + // } + // FindAssetById(query) => { + // let asset_id = try_evaluate_or_deny!(query.id, wsv); + // if asset_id.account_id.domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access asset {} as it is in a different domain.", + // asset_id + // )) + // } + // } + // FindAssetsByAccountId(query) => { + // let account_id = try_evaluate_or_deny!(query.account_id, wsv); + // if *account_id.domain_id().expect("Valid") == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access account {} as it is in a different domain.", + // account_id + // )) + // } + // } + // FindAssetsByDomainId(query) => { + // let domain_id = try_evaluate_or_deny!(query.domain_id, wsv); + // if domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access assets from a different domain with name {}.", + // domain_id + // )) + // } + // } + // FindAssetsByDomainIdAndAssetDefinitionId(query) => { + // let domain_id = try_evaluate_or_deny!(query.domain_id, wsv); + // if domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access assets from a different domain with name {}.", + // domain_id + // )) + // } + // } + // FindAssetDefinitionKeyValueByIdAndKey(query) => { + // let asset_definition_id = try_evaluate_or_deny!(query.id, wsv); + // if asset_definition_id.domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access asset definition from a different domain. Asset definition domain: {}. Signer's account domain {}.", + // asset_definition_id.domain_id, + // authority_domain + // )) + // } + // } + // FindAssetQuantityById(query) => { + // let asset_id = try_evaluate_or_deny!(query.id, wsv); + // if asset_id.account_id.domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access asset {} as it is in a different domain.", + // asset_id + // )) + // } + // } + // FindAssetKeyValueByIdAndKey(query) => { + // let asset_id = try_evaluate_or_deny!(query.id, wsv); + // if asset_id.account_id.domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access asset {} as it is in a different domain.", + // asset_id + // )) + // } + // } + // FindDomainById(query::FindDomainById { id }) + // | FindDomainKeyValueByIdAndKey(query::FindDomainKeyValueByIdAndKey { id, .. }) => { + // let domain_id = try_evaluate_or_deny!(id, wsv); + // if domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!("Cannot access a different domain: {}.", domain_id)) + // } + // } + // FindAllBlocks(_) => Deny("You are not permitted to access all blocks.".to_owned()), + // FindAllBlockHeaders(_) => { + // Deny("You are not permitted to access all blocks.".to_owned()) + // } + // FindBlockHeaderByHash(_) => { + // Deny("You are not permitted to access arbitrary blocks.".to_owned()) + // } + // FindAllTransactions(_) => { + // Deny("Cannot access transactions of another domain.".to_owned()) + // } + // FindTransactionsByAccountId(query) => { + // let account_id = try_evaluate_or_deny!(query.account_id, wsv); + // if account_id.domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access account {} as it is in a different domain.", + // account_id + // )) + // } + // } + // FindTransactionByHash(_query) => Allow, + // FindRolesByAccountId(query) => { + // let account_id = try_evaluate_or_deny!(query.id, wsv); + // if account_id.domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access account {} as it is in a different domain.", + // account_id + // )) + // } + // } + // FindPermissionTokensByAccountId(query) => { + // let account_id = try_evaluate_or_deny!(query.id, wsv); + // if account_id.domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access account {} as it is in a different domain.", + // account_id + // )) + // } + // } + // FindAssetDefinitionById(query) => { + // let asset_definition_id = try_evaluate_or_deny!(query.id, wsv); - if asset_definition_id.domain_id == authority.domain_id { - Allow - } else { - Deny(format!( - "Cannot access asset definition from a different domain. Asset definition domain: {}. Signer's account domain {}.", - asset_definition_id.domain_id, - authority.domain_id, - )) - } - } - } + // if asset_definition_id.domain_id == *authority_domain { + // Allow + // } else { + // Deny(format!( + // "Cannot access asset definition from a different domain. Asset definition domain: {}. Signer's account domain {}.", + // asset_definition_id.domain_id, + // authority_domain, + // )) + // } + // } + // } + // } } } @@ -305,7 +308,7 @@ impl IsAllowed for OnlyAccountsData { | FindAllAccounts(_) => { Deny("Other accounts are private.".to_owned()) } - | FindAllDomains(_) + | FindAllDomains(_) | FindDomainById(_) | FindDomainKeyValueByIdAndKey(_) => { Deny("Only the access to the data in your own account is permitted.".to_owned()) @@ -333,7 +336,7 @@ impl IsAllowed for OnlyAccountsData { // TODO: should differentiate between global and domain-local triggers. let id = try_evaluate_or_deny!(query.id, wsv); if wsv.triggers().inspect_by_id(&id, |action| - action.technical_account() == authority + action.technical_account() == authority ) == Some(true) { return Allow } @@ -346,7 +349,7 @@ impl IsAllowed for OnlyAccountsData { // TODO: should differentiate between global and domain-local triggers. let id = try_evaluate_or_deny!(query.id, wsv); if wsv.triggers().inspect_by_id(&id, |action| - action.technical_account() == authority + action.technical_account() == authority ) == Some(true) { return Allow } @@ -355,9 +358,29 @@ impl IsAllowed for OnlyAccountsData { id )) } + FindAccountIdByAlias(query) => { + let account_id = try_evaluate_or_deny!(query.alias, wsv); + if let Some(ref authority_alias) = authority.alias { + if account_id == *authority_alias { + Allow + } else { + Deny(format!( + "Cannot access account {} as only access to your own account, {} is permitted..", + account_id, + authority + )) + } + } else { + Deny(format!( + "Cannot access account {} as only access to your own account, {} is permitted..", + account_id, + authority + )) + } + } FindAccountById(query) => { let account_id = try_evaluate_or_deny!(query.id, wsv); - if &account_id == authority { + if account_id == *authority { Allow } else { Deny(format!( @@ -369,7 +392,7 @@ impl IsAllowed for OnlyAccountsData { } FindAccountKeyValueByIdAndKey(query) => { let account_id = try_evaluate_or_deny!(query.id, wsv); - if &account_id == authority { + if account_id == *authority { Allow } else { Deny(format!( @@ -380,7 +403,7 @@ impl IsAllowed for OnlyAccountsData { } FindAssetById(query) => { let asset_id = try_evaluate_or_deny!(query.id, wsv); - if &asset_id.account_id == authority { + if asset_id.account_id == *authority { Allow } else { Deny(format!( @@ -390,9 +413,8 @@ impl IsAllowed for OnlyAccountsData { } } FindAssetsByAccountId(query) => { - let account_id = try_evaluate_or_deny!(query - .account_id, wsv); - if &account_id == authority { + let account_id = try_evaluate_or_deny!(query.account_id, wsv); + if account_id == *authority { Allow } else { Deny(format!( @@ -401,10 +423,9 @@ impl IsAllowed for OnlyAccountsData { )) } } - FindAssetQuantityById(query) => { let asset_id = try_evaluate_or_deny!(query.id, wsv); - if &asset_id.account_id == authority { + if asset_id.account_id == *authority { Allow } else { Deny(format!( @@ -415,7 +436,7 @@ impl IsAllowed for OnlyAccountsData { } FindAssetKeyValueByIdAndKey(query) => { let asset_id = try_evaluate_or_deny!(query.id, wsv); - if &asset_id.account_id == authority { + if asset_id.account_id == *authority { Allow } else { Deny(format!( @@ -437,9 +458,8 @@ impl IsAllowed for OnlyAccountsData { Deny("Cannot access transactions of another account.".to_owned()) }, FindTransactionsByAccountId(query) => { - let account_id = try_evaluate_or_deny!(query - .account_id, wsv); - if &account_id == authority { + let account_id = try_evaluate_or_deny!(query.account_id, wsv); + if account_id == *authority { Allow } else { Deny(format!("Cannot access another account: {}.", account_id)) @@ -448,7 +468,7 @@ impl IsAllowed for OnlyAccountsData { FindTransactionByHash(_query) => Allow, FindRolesByAccountId(query) => { let account_id = try_evaluate_or_deny!(query.id, wsv); - if &account_id == authority { + if account_id == *authority { Allow } else { Deny(format!("Cannot access another account: {}.", account_id)) @@ -457,7 +477,7 @@ impl IsAllowed for OnlyAccountsData { FindAllPermissionTokenDefinitions(_) => Deny("Only the access to the permission tokens of your own account is permitted.".to_owned()), FindPermissionTokensByAccountId(query) => { let account_id = try_evaluate_or_deny!(query.id, wsv); - if &account_id == authority { + if account_id == *authority { Allow } else { Deny(format!("Cannot access another account: {}.", account_id)) diff --git a/permissions_validators/src/private_blockchain/tests/mod.rs b/permissions_validators/src/private_blockchain/tests/mod.rs index 828807bbbb3..fcab446d742 100644 --- a/permissions_validators/src/private_blockchain/tests/mod.rs +++ b/permissions_validators/src/private_blockchain/tests/mod.rs @@ -40,8 +40,14 @@ struct TestEnv { impl TestEnv { /// Create a test environment fn new() -> Self { - let alice_id = AccountId::from_str("alice@wonderland").expect("Valid"); - let mut alice = Account::new(alice_id.clone(), []).build(); + let alice_id = { + let alias = Alias::from_str("alice@wonderland").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let mut alice = Account::from_id(alice_id.clone()).build(); + + let gold_asset_definition_id = AssetDefinitionId::from_str("gold#wonderland").expect("Valid"); @@ -50,8 +56,13 @@ impl TestEnv { alice.add_asset(gold_asset); - let bob_id = AccountId::from_str("bob@wonderland").expect("Valid"); - let mut bob = Account::new(bob_id.clone(), []).build(); + let bob_id = { + let alias = Alias::from_str("bob@wonderland").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + + let mut bob = Account::from_id(bob_id.clone()).build(); let silver_asset_definition_id = AssetDefinitionId::from_str("silver#wonderland").expect("Valid"); @@ -60,8 +71,13 @@ impl TestEnv { bob.add_asset(silver_asset); - let carol_id = AccountId::from_str("carol@denoland").expect("Valid"); - let mut carol = Account::new(carol_id.clone(), []).build(); + + let carol_id = { + let alias = Alias::from_str("alice@wonderland").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let mut carol = Account::from_id(carol_id.clone()).build(); let bronze_asset_definition_id = AssetDefinitionId::from_str("bronze#denoland").expect("Valid"); diff --git a/permissions_validators/src/private_blockchain/tests/revoke_and_grant.rs b/permissions_validators/src/private_blockchain/tests/revoke_and_grant.rs index 77c65ce9095..6fd5b4ba93f 100644 --- a/permissions_validators/src/private_blockchain/tests/revoke_and_grant.rs +++ b/permissions_validators/src/private_blockchain/tests/revoke_and_grant.rs @@ -2,7 +2,11 @@ use super::*; #[test] fn add_register_domains_permission_denies_registering_domain() { - let alice_id = AccountId::from_str("alice@test0").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test0").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let instruction = Instruction::Register(RegisterBox::new(Domain::new( "new_domain".parse().expect("Valid"), @@ -17,7 +21,11 @@ fn add_register_domains_permission_denies_registering_domain() { #[test] fn add_register_domains_permission_allows_registering_account() { - let alice_id = AccountId::from_str("alice@test0").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test0").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let instruction = Instruction::Register(RegisterBox::new(Account::new( "bob@test".parse().expect("Valid"), @@ -33,13 +41,22 @@ fn add_register_domains_permission_allows_registering_account() { #[test] fn add_register_domains_permission_allows_registering_domain_with_right_token() { - let alice_id = AccountId::from_str("alice@test0").expect("Valid"); - let mut alice = Account::new(alice_id.clone(), []).build(); + let alice_id = { + let alias = Alias::from_str("alice@test0").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + + let mut alice = Account::from_id(alice_id.clone()).build(); alice.add_permission(register::CanRegisterDomains::new().into()); - let bob_id = AccountId::from_str("bob@test0").expect("Valid"); - let bob = Account::new(bob_id.clone(), []).build(); + let bob_id = { + let alias = Alias::from_str("bob@test0").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob = Account::from_id(bob_id.clone()).build(); let domain_id = DomainId::from_str("test0").expect("Valid"); let mut domain = Domain::new(domain_id).build(); @@ -60,9 +77,13 @@ fn add_register_domains_permission_allows_registering_domain_with_right_token() #[test] fn add_register_domains_permission_denies_registering_domain_with_wrong_token() { - let alice_id = AccountId::from_str("alice@test0").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test0").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; - let mut alice = Account::new(alice_id.clone(), []).build(); + let mut alice = Account::from_id(alice_id.clone()).build(); alice.add_permission(PermissionToken::new( "incorrecttoken".parse().expect("Valid"), )); diff --git a/permissions_validators/src/public_blockchain/mod.rs b/permissions_validators/src/public_blockchain/mod.rs index b1bbe2c4e72..7c525208609 100644 --- a/permissions_validators/src/public_blockchain/mod.rs +++ b/permissions_validators/src/public_blockchain/mod.rs @@ -194,15 +194,23 @@ mod tests { #[test] fn transfer_only_owned_assets() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone(), ); let bob_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("bob@test").expect("Valid"), + bob_id.clone() ); let wsv = WorldStateView::new(World::new()); let transfer = Instruction::Transfer(TransferBox { @@ -220,18 +228,26 @@ mod tests { #[test] fn transfer_granted_assets() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone(), ); let bob_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("bob@test").expect("Valid"), + bob_id.clone(), ); let mut domain = Domain::new(DomainId::from_str("test").expect("Valid")).build(); - let mut bob_account = Account::new(bob_id.clone(), []).build(); + let mut bob_account = Account::from_id(bob_id.clone()).build(); assert!(bob_account .add_permission(transfer::CanTransferUserAssets::new(alice_xor_id.clone()).into())); assert!(domain.add_account(bob_account).is_none()); @@ -249,11 +265,19 @@ mod tests { #[test] fn grant_transfer_of_my_assets() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone() ); let permission_token_to_alice: PermissionToken = transfer::CanTransferUserAssets::new(alice_xor_id).into(); @@ -269,15 +293,23 @@ mod tests { #[test] fn unregister_only_assets_created_by_this_account() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("Valid"); let xor_definition = new_xor_definition(&xor_id); let domain_id = DomainId::from_str("test").expect("Valid"); let mut domain = Domain::new(domain_id).build(); assert!(domain - .add_asset_definition(xor_definition, alice_id.clone()) - .is_none()); + .add_asset_definition(xor_definition, alice_id.clone()) + .is_none()); let wsv = WorldStateView::new(World::with([domain], [])); let unregister = Instruction::Unregister(UnregisterBox::new(IdBox::AssetDefinitionId(xor_id))); @@ -291,12 +323,20 @@ mod tests { #[test] fn unregister_granted_assets() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("Valid"); let xor_definition = new_xor_definition(&xor_id); let mut domain = Domain::new(DomainId::from_str("test").expect("Valid")).build(); - let mut bob_account = Account::new(bob_id.clone(), []).build(); + let mut bob_account = Account::from_id(bob_id.clone()).build(); assert!(bob_account.add_permission( unregister::CanUnregisterAssetWithDefinition::new(xor_id.clone()).into() )); @@ -314,8 +354,16 @@ mod tests { #[test] fn grant_unregister_of_assets_created_by_this_account() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("Valid"); let xor_definition = new_xor_definition(&xor_id); let permission_token_to_alice: PermissionToken = @@ -337,12 +385,20 @@ mod tests { #[test] fn mint_only_assets_created_by_this_account() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone(), ); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("Valid"); let xor_definition = new_xor_definition(&xor_id); let domain_id = DomainId::from_str("test").expect("Valid"); @@ -365,16 +421,24 @@ mod tests { #[test] fn mint_granted_assets() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone(), ); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("Valid"); let xor_definition = new_xor_definition(&xor_id); let mut domain = Domain::new(DomainId::from_str("test").expect("Valid")).build(); - let mut bob_account = Account::new(bob_id.clone(), []).build(); + let mut bob_account = Account::from_id(bob_id.clone()).build(); assert!(bob_account.add_permission(mint::CanMintUserAssetDefinitions::new(xor_id).into())); assert!(domain.add_account(bob_account).is_none()); assert!(domain @@ -393,8 +457,16 @@ mod tests { #[test] fn grant_mint_of_assets_created_by_this_account() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("Valid"); let xor_definition = new_xor_definition(&xor_id); let permission_token_to_alice: PermissionToken = @@ -415,12 +487,21 @@ mod tests { #[test] fn burn_only_assets_created_by_this_account() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone(), ); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("Valid"); let xor_definition = new_xor_definition(&xor_id); let domain_id = DomainId::from_str("test").expect("Valid"); @@ -443,21 +524,29 @@ mod tests { #[test] fn burn_granted_asset_definition() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone() ); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("Valid"); let xor_definition = new_xor_definition(&xor_id); let mut domain = Domain::new(DomainId::from_str("test").expect("Valid")).build(); - let mut bob_account = Account::new(bob_id.clone(), []).build(); + let mut bob_account = Account::from_id(bob_id.clone()).build(); assert!(bob_account.add_permission(burn::CanBurnAssetWithDefinition::new(xor_id).into())); assert!(domain.add_account(bob_account).is_none()); assert!(domain - .add_asset_definition(xor_definition, alice_id.clone()) - .is_none()); + .add_asset_definition(xor_definition, alice_id.clone()) + .is_none()); let wsv = WorldStateView::new(World::with([domain], vec![])); let instruction = Instruction::Burn(BurnBox { object: Value::U32(100).into(), @@ -471,8 +560,16 @@ mod tests { #[test] fn grant_burn_of_assets_created_by_this_account() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("Valid"); let xor_definition = new_xor_definition(&xor_id); let permission_token_to_alice: PermissionToken = @@ -493,11 +590,19 @@ mod tests { #[test] fn burn_only_owned_assets() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@tests").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone(), ); let wsv = WorldStateView::new(World::new()); let burn = Instruction::Burn(BurnBox { @@ -512,14 +617,22 @@ mod tests { #[test] fn burn_granted_assets() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone(), ); let mut domain = Domain::new(DomainId::from_str("test").expect("Valid")).build(); - let mut bob_account = Account::new(bob_id.clone(), []).build(); + let mut bob_account = Account::from_id(bob_id.clone()).build(); assert!( bob_account.add_permission(burn::CanBurnUserAssets::new(alice_xor_id.clone()).into()) ); @@ -536,11 +649,19 @@ mod tests { #[test] fn grant_burn_of_my_assets() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone() ); let permission_token_to_alice: PermissionToken = burn::CanBurnUserAssets::new(alice_xor_id).into(); @@ -556,11 +677,19 @@ mod tests { #[test] fn set_to_only_owned_assets() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone(), ); let wsv = WorldStateView::new(World::new()); let key: Name = "key".parse().expect("Valid"); @@ -579,28 +708,44 @@ mod tests { #[test] fn remove_to_only_owned_assets() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("valid name"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let alice_xor_id = ::Id::new( AssetDefinitionId::from_str("xor#test").expect("Valid"), - AccountId::from_str("alice@test").expect("Valid"), + alice_id.clone(), ); let wsv = WorldStateView::new(World::new()); let key: Name = "key".parse().expect("Valid"); let set = Instruction::RemoveKeyValue(RemoveKeyValueBox::new(IdBox::AssetId(alice_xor_id), key)); assert!(key_value::AssetRemoveOnlyForSignerAccount - .check(&alice_id, &set, &wsv) - .is_allow()); + .check(&alice_id, &set, &wsv) + .is_allow()); assert!(key_value::AssetRemoveOnlyForSignerAccount - .check(&bob_id, &set, &wsv) - .is_deny()); + .check(&bob_id, &set, &wsv) + .is_deny()); } #[test] fn set_to_only_owned_account() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let wsv = WorldStateView::new(World::new()); let key: Name = "key".parse().expect("Valid"); let set = Instruction::SetKeyValue(SetKeyValueBox::new( @@ -618,8 +763,16 @@ mod tests { #[test] fn remove_to_only_owned_account() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let wsv = WorldStateView::new(World::new()); let key: Name = "key".parse().expect("Valid"); let set = Instruction::RemoveKeyValue(RemoveKeyValueBox::new( @@ -636,8 +789,16 @@ mod tests { #[test] fn set_to_only_owned_asset_definition() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("Valid"); let xor_definition = new_xor_definition(&xor_id); let domain_id = DomainId::from_str("test").expect("Valid"); @@ -662,8 +823,16 @@ mod tests { #[test] fn remove_to_only_owned_asset_definition() { - let alice_id = AccountId::from_str("alice@test").expect("Valid"); - let bob_id = AccountId::from_str("bob@test").expect("Valid"); + let alice_id = { + let alias = Alias::from_str("alice@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; + let bob_id = { + let alias = Alias::from_str("bob@test").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let xor_id = AssetDefinitionId::from_str("xor#test").expect("Valid"); let xor_definition = new_xor_definition(&xor_id); let domain_id = DomainId::from_str("test").expect("Valid"); diff --git a/tools/kagami/src/main.rs b/tools/kagami/src/main.rs index 80f4a94773c..4a322edb25f 100644 --- a/tools/kagami/src/main.rs +++ b/tools/kagami/src/main.rs @@ -17,8 +17,8 @@ pub type Outcome = color_eyre::Result<()>; // The reason for hard-coding this default is to ensure that the // algorithm is matched to the public key. If you need to change // either, you should definitely change both. -static DEFAULT_PUBLIC_KEY: &str = - "ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0"; +// static DEFAULT_PUBLIC_KEY: &str = +// "ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0"; // static DEFAULT_ALGORITHM: &str = iroha_crypto::ED_25519; fn main() -> Outcome { @@ -186,27 +186,28 @@ mod genesis { } pub fn generate_default() -> color_eyre::Result { - let mut result = RawGenesisBlockBuilder::new() - .domain("wonderland".parse()?) - .with_account("alice".parse()?, crate::DEFAULT_PUBLIC_KEY.parse()?) - .with_asset("rose".parse()?, AssetValueType::Quantity) - .finish_domain() - .build(); - let mint = MintBox::new( - iroha_data_model::prelude::Value::U32(13_u32), - iroha_data_model::IdBox::AssetId(iroha_data_model::prelude::AssetId::new( - "rose#wonderland".parse()?, - "alice@wonderland".parse()?, - )), - ); - - result.transactions[0].isi.extend( - public_blockchain::default_permission_token_definitions() - .into_iter() - .map(|token_definition| RegisterBox::new(token_definition.clone()).into()), - ); - result.transactions[0].isi.push(mint.into()); - Ok(result) + // let mut result = RawGenesisBlockBuilder::new() + // .domain("wonderland".parse()?) + // .with_account("alice".parse()?, crate::DEFAULT_PUBLIC_KEY.parse()?) + // .with_asset("rose".parse()?, AssetValueType::Quantity) + // .finish_domain() + // .build(); + // let mint = MintBox::new( + // iroha_data_model::prelude::Value::U32(13_u32), + // iroha_data_model::IdBox::AssetId(iroha_data_model::prelude::AssetId::new( + // "rose#wonderland".parse()?, + // "alice@wonderland".parse()?, + // )), + // ); + + // result.transactions[0].isi.extend( + // public_blockchain::default_permission_token_definitions() + // .into_iter() + // .map(|token_definition| RegisterBox::new(token_definition.clone()).into()), + // ); + // result.transactions[0].isi.push(mint.into()); + // Ok(result) + todo!() } } diff --git a/tools/parity_scale_decoder/Cargo.toml b/tools/parity_scale_decoder/Cargo.toml index f9f7b68458e..e0a2778de28 100644 --- a/tools/parity_scale_decoder/Cargo.toml +++ b/tools/parity_scale_decoder/Cargo.toml @@ -31,3 +31,4 @@ iroha_data_model = { version = "=2.0.0-pre-rc.7", path = "../../data_model", fea parity-scale-codec = { version = "3.1.5", default-features = false } serde_json = "1.0.83" serde = "1.0.142" +eyre = "0.6.8" diff --git a/tools/parity_scale_decoder/build.rs b/tools/parity_scale_decoder/build.rs index 612da7e76d6..01cbebf0793 100644 --- a/tools/parity_scale_decoder/build.rs +++ b/tools/parity_scale_decoder/build.rs @@ -7,14 +7,15 @@ use std::{fs, io::Result, path::PathBuf}; use iroha_data_model::prelude::*; use parity_scale_codec::Encode; use serde::de::DeserializeOwned; +use eyre::WrapErr as _; -fn main() { - sample_into_binary_file::("account").expect("Failed to encode into account.bin."); +fn main() -> eyre::Result<()> { + sample_into_binary_file::("account").wrap_err("Failed to decode sample `account.json`")?; - sample_into_binary_file::("domain").expect("Failed to encode into domain.bin."); + sample_into_binary_file::("domain").wrap_err("Failed to decode sample `domain.json`")?; - sample_into_binary_file::>("trigger") - .expect("Failed to encode into trigger.bin."); + sample_into_binary_file::>("trigger").wrap_err("Failed to decode sample `trigger`")?; + Ok(()) } fn sample_into_binary_file(filename: &str) -> Result<()> diff --git a/tools/parity_scale_decoder/samples/account.bin b/tools/parity_scale_decoder/samples/account.bin index 1f75361f6fec3f97808466312273ed834045b776..67f8f3418e78dbaa7c202f7c41db41a5dfb9e559 100644 GIT binary patch delta 50 zcmV-20L}kUZz>#RWHL21F*$%7Vfy&~l;TslF%%>Nl=qrodw->0o?1cc>~y$*Rd$O3 IkV66h02o~r8vpiDU|`_oU={$0Xq4yYrKA?+B<7{aq^1~|ni^U*$Rz&y z@o&nb;GKpdD$G;9&q}DSUm8Cz%JKD^k{u19W!;P-i8-0c$XXdF(96ik#J~Um%t1ZO delta 46 mcmZ3?=s!VSLnJXLGdWeGJU=fbwJ0YsFNFa^gprYnfdK$;Uk;}L diff --git a/tools/parity_scale_decoder/samples/trigger.json b/tools/parity_scale_decoder/samples/trigger.json index bea25ec0bba..37525dd04ea 100644 --- a/tools/parity_scale_decoder/samples/trigger.json +++ b/tools/parity_scale_decoder/samples/trigger.json @@ -1,55 +1,61 @@ { - "id": { - "name": "mint_rose" - }, - "action": { - "executable": { - "Instructions": [ - { - "Mint": { - "object": { - "Raw": { - "U32": 1 - } - }, - "destination_id": { - "Raw": { - "Id": { - "AssetId": { - "definition_id": { - "name": "rose", - "domain_id": { - "name": "wonderland" - } - }, - "account_id": { - "name": "alice", - "domain_id": { - "name": "wonderland" - } - } - } - } - } + "id": { + "name": "mint_rose" + }, + "action": { + "executable": { + "Instructions": [ + { + "Mint": { + "object": { + "Raw": { + "U32": 1 + } + }, + "destination_id": { + "Raw": { + "Id": { + "AssetId": { + "definition_id": { + "name": "rose", + "domain_id": { + "name": "wonderland" + } + }, + "account_id": { + "primary_key": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b", + "alias": { + "name": "alice", + "domain_id": { + "name": "wonderland" } + } } + } } - ] - }, - "repeats": "Indefinitely", - "technical_account": { - "name": "alice", - "domain_id": { - "name": "wonderland" - } - }, - "filter": { - "Data": { - "BySome": { - "ByAccount": "AcceptAll" - } + } } - }, - "metadata": {} - } + } + } + ] + }, + "repeats": "Indefinitely", + "technical_account": { + "primary_key": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b", + "alias": { + "name": "alice", + "domain_id": { + "name": "wonderland" + } + } + }, + "filter": { + "Data": { + "BySome": { + "ByAccount": "AcceptAll" + } + } + }, + "metadata": {} + } } diff --git a/tools/parity_scale_decoder/src/main.rs b/tools/parity_scale_decoder/src/main.rs index 6afb38749ea..dadc660d897 100644 --- a/tools/parity_scale_decoder/src/main.rs +++ b/tools/parity_scale_decoder/src/main.rs @@ -160,6 +160,7 @@ mod tests { use std::str::FromStr as _; + use iroha_crypto::KeyPair; use iroha_data_model::{domain::IpfsPath, prelude::*}; use super::*; @@ -214,8 +215,11 @@ mod tests { #[test] fn decode_trigger_sample() { - let account_id = - ::Id::from_str("alice@wonderland").expect("Valid"); + let account_id = { + let alias = Alias::from_str("alice@wonderland").expect("Valid"); + let (public_key, _) = KeyPair::generate().expect("Valid").into(); + AccountId::new(public_key, alias) + }; let rose_definition_id = ::Id::new( "rose".parse().expect("Valid"), "wonderland".parse().expect("Valid"),