diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 5dbf5318efd..95030eecf89 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -472,7 +472,7 @@ enum TelemetryStartStatus { } fn genesis_account(public_key: PublicKey) -> Account { - Account::new(iroha_genesis::GENESIS_ACCOUNT_ID.clone(), [public_key]) + Account::new(iroha_genesis::GENESIS_ACCOUNT_ID.clone(), public_key) .build(&iroha_genesis::GENESIS_ACCOUNT_ID) } diff --git a/client/benches/torii.rs b/client/benches/torii.rs index 669fcc0c917..e9bb7f48008 100644 --- a/client/benches/torii.rs +++ b/client/benches/torii.rs @@ -64,7 +64,7 @@ fn query_requests(criterion: &mut Criterion) { let create_domain = Register::domain(Domain::new(domain_id.clone())); let account_id = AccountId::new(domain_id.clone(), "account".parse().expect("Valid")); let (public_key, _) = KeyPair::generate().into(); - let create_account = Register::account(Account::new(account_id.clone(), [public_key])); + let create_account = Register::account(Account::new(account_id.clone(), public_key)); let asset_definition_id = AssetDefinitionId::new(domain_id, "xor".parse().expect("Valid")); let create_asset = Register::asset_definition(AssetDefinition::quantity(asset_definition_id.clone())); @@ -164,7 +164,7 @@ fn instruction_submits(criterion: &mut Criterion) { let create_domain: InstructionBox = Register::domain(Domain::new(domain_id.clone())).into(); let account_id = AccountId::new(domain_id.clone(), "account".parse().expect("Valid")); let (public_key, _) = KeyPair::generate().into(); - let create_account = Register::account(Account::new(account_id.clone(), [public_key])).into(); + let create_account = Register::account(Account::new(account_id.clone(), public_key)).into(); let asset_definition_id = AssetDefinitionId::new(domain_id, "xor".parse().expect("Valid")); let client_config = iroha_client::samples::get_client_config( get_chain_id(), diff --git a/client/benches/tps/utils.rs b/client/benches/tps/utils.rs index f078481269b..6d417b2e9e4 100644 --- a/client/benches/tps/utils.rs +++ b/client/benches/tps/utils.rs @@ -158,8 +158,7 @@ impl MeasurerUnit { let account_id = account_id(self.name); let asset_id = asset_id(self.name); - let register_me = - Register::account(Account::new(account_id, [keypair.public_key().clone()])); + let register_me = Register::account(Account::new(account_id, keypair.public_key().clone())); self.client.submit_blocking(register_me)?; let mint_a_rose = Mint::asset_quantity(1_u32, asset_id); diff --git a/client/examples/million_accounts_genesis.rs b/client/examples/million_accounts_genesis.rs index c618caf700b..d6a0d080500 100644 --- a/client/examples/million_accounts_genesis.rs +++ b/client/examples/million_accounts_genesis.rs @@ -77,7 +77,10 @@ fn create_million_accounts_directly() { format!("bob-{i}").parse().expect("Valid"), ); let create_domain: InstructionBox = Register::domain(Domain::new(domain_id)).into(); - let create_account = Register::account(Account::new(normal_account_id.clone(), [])).into(); + let create_account = Register::account(Account::new_with_random_signature( + normal_account_id.clone(), + )) + .into(); if test_client .submit_all([create_domain, create_account]) .is_err() diff --git a/client/examples/tutorial.rs b/client/examples/tutorial.rs index bec8227f6a5..b58dbdc95df 100644 --- a/client/examples/tutorial.rs +++ b/client/examples/tutorial.rs @@ -120,7 +120,7 @@ fn account_registration_test(config: Config) -> Result<(), Error> { // #region register_account_generate // Generate a new account - let create_account = Register::account(Account::new(account_id, [public_key])); + let create_account = Register::account(Account::new(account_id, public_key)); // #endregion register_account_generate // #region register_account_prepare_tx diff --git a/client/tests/integration/add_account.rs b/client/tests/integration/add_account.rs index 49d15f1ebd9..3a06ac014d1 100644 --- a/client/tests/integration/add_account.rs +++ b/client/tests/integration/add_account.rs @@ -16,14 +16,18 @@ fn client_add_account_with_name_length_more_than_limit_should_not_commit_transac let pipeline_time = Config::pipeline_time(); let normal_account_id: AccountId = "bob@wonderland".parse().expect("Valid"); - let create_account = Register::account(Account::new(normal_account_id.clone(), [])); + let create_account = Register::account(Account::new_with_random_signature( + 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 = Register::account(Account::new(incorrect_account_id.clone(), [])); + let create_account = Register::account(Account::new_with_random_signature( + incorrect_account_id.clone(), + )); test_client.submit(create_account)?; thread::sleep(pipeline_time * 2); diff --git a/client/tests/integration/asset.rs b/client/tests/integration/asset.rs index 3c3d719d694..180376ee8b0 100644 --- a/client/tests/integration/asset.rs +++ b/client/tests/integration/asset.rs @@ -271,7 +271,7 @@ fn find_rate_and_make_exchange_isi_should_succeed() { let buyer_keypair = KeyPair::generate(); let register_account = |account_id: AccountId, signature: PublicKey| { - Register::account(Account::new(account_id, [signature])) + Register::account(Account::new(account_id, signature)) }; let grant_alice_asset_transfer_permission = |asset_id: AssetId, owner_keypair: KeyPair| { @@ -454,13 +454,10 @@ mod register { } pub fn account(account_name: &str, domain_name: &str) -> Register { - Register::account(Account::new( - AccountId::new( - domain_name.parse().expect("Valid"), - account_name.parse().expect("Valid"), - ), - [], - )) + Register::account(Account::new_with_random_signature(AccountId::new( + domain_name.parse().expect("Valid"), + account_name.parse().expect("Valid"), + ))) } pub fn asset_definition(asset_name: &str, domain_name: &str) -> Register { diff --git a/client/tests/integration/asset_propagation.rs b/client/tests/integration/asset_propagation.rs index 29122fc9560..c26d142e67e 100644 --- a/client/tests/integration/asset_propagation.rs +++ b/client/tests/integration/asset_propagation.rs @@ -32,7 +32,7 @@ fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount_on_a Register::domain(Domain::new(DomainId::from_str("domain")?)).into(); let account_id = AccountId::from_str("account@domain")?; let (public_key, _) = KeyPair::generate().into(); - let create_account = Register::account(Account::new(account_id.clone(), [public_key])).into(); + let create_account = Register::account(Account::new(account_id.clone(), public_key)).into(); let asset_definition_id = AssetDefinitionId::from_str("xor#domain")?; let create_asset = Register::asset_definition(AssetDefinition::quantity(asset_definition_id.clone())).into(); diff --git a/client/tests/integration/burn_public_keys.rs b/client/tests/integration/burn_public_keys.rs index a50bb6cec0e..b28c9637eae 100644 --- a/client/tests/integration/burn_public_keys.rs +++ b/client/tests/integration/burn_public_keys.rs @@ -52,7 +52,7 @@ fn public_keys_cannot_be_burned_to_nothing() { let charlie_initial_keypair = KeyPair::generate(); let register_charlie = Register::account(Account::new( charlie_id.clone(), - [charlie_initial_keypair.public_key().clone()], + charlie_initial_keypair.public_key().clone(), )); let (tx_hash, res) = submit(&client, [register_charlie], None); diff --git a/client/tests/integration/domain_owner_permissions.rs b/client/tests/integration/domain_owner_permissions.rs index d2901928317..3f791401bcd 100644 --- a/client/tests/integration/domain_owner_permissions.rs +++ b/client/tests/integration/domain_owner_permissions.rs @@ -23,7 +23,7 @@ fn domain_owner_domain_permissions() -> Result<()> { test_client.submit_blocking(Register::domain(kingdom))?; let bob_keypair = KeyPair::generate(); - let bob = Account::new(bob_id.clone(), [bob_keypair.public_key().clone()]); + let bob = Account::new(bob_id.clone(), bob_keypair.public_key().clone()); test_client.submit_blocking(Register::account(bob))?; // Asset definitions can't be registered by "bob@kingdom" by default @@ -96,7 +96,7 @@ fn domain_owner_account_permissions() -> Result<()> { let mad_hatter_keypair = KeyPair::generate(); let mad_hatter = Account::new( mad_hatter_id.clone(), - [mad_hatter_keypair.public_key().clone()], + mad_hatter_keypair.public_key().clone(), ); test_client.submit_blocking(Register::account(mad_hatter))?; @@ -158,10 +158,10 @@ fn domain_owner_asset_definition_permissions() -> Result<()> { test_client.submit_blocking(Register::domain(kingdom))?; let bob_keypair = KeyPair::generate(); - let bob = Account::new(bob_id.clone(), [bob_keypair.public_key().clone()]); + let bob = Account::new(bob_id.clone(), bob_keypair.public_key().clone()); test_client.submit_blocking(Register::account(bob))?; - let rabbit = Account::new(rabbit_id.clone(), []); + let rabbit = Account::new_with_random_signature(rabbit_id.clone()); test_client.submit_blocking(Register::account(rabbit))?; // Grant permission to register asset definitions to "bob@kingdom" @@ -228,7 +228,7 @@ fn domain_owner_asset_permissions() -> Result<()> { test_client.submit_blocking(Register::domain(kingdom))?; let bob_keypair = KeyPair::generate(); - let bob = Account::new(bob_id.clone(), [bob_keypair.public_key().clone()]); + let bob = Account::new(bob_id.clone(), bob_keypair.public_key().clone()); test_client.submit_blocking(Register::account(bob))?; // Grant permission to register asset definitions to "bob@kingdom" @@ -293,7 +293,7 @@ fn domain_owner_trigger_permissions() -> Result<()> { test_client.submit_blocking(Register::domain(kingdom))?; let bob_keypair = KeyPair::generate(); - let bob = Account::new(bob_id.clone(), [bob_keypair.public_key().clone()]); + let bob = Account::new(bob_id.clone(), bob_keypair.public_key().clone()); test_client.submit_blocking(Register::account(bob))?; let asset_definition_id = "rose#wonderland".parse()?; @@ -354,7 +354,7 @@ fn domain_owner_transfer() -> Result<()> { test_client.submit_blocking(Register::domain(kingdom))?; let bob_keypair = KeyPair::generate(); - let bob = Account::new(bob_id.clone(), [bob_keypair.public_key().clone()]); + let bob = Account::new(bob_id.clone(), bob_keypair.public_key().clone()); test_client.submit_blocking(Register::account(bob))?; let domain = test_client.request(FindDomainById::new(kingdom_id.clone()))?; diff --git a/client/tests/integration/extra_functional/multiple_blocks_created.rs b/client/tests/integration/extra_functional/multiple_blocks_created.rs index 1b56abe5590..081c30e91a3 100644 --- a/client/tests/integration/extra_functional/multiple_blocks_created.rs +++ b/client/tests/integration/extra_functional/multiple_blocks_created.rs @@ -31,7 +31,7 @@ fn long_multiple_blocks_created() -> Result<()> { let create_domain: InstructionBox = Register::domain(Domain::new("domain".parse()?)).into(); let account_id: AccountId = "account@domain".parse()?; let (public_key, _) = KeyPair::generate().into(); - let create_account = Register::account(Account::new(account_id.clone(), [public_key])).into(); + let create_account = Register::account(Account::new(account_id.clone(), public_key)).into(); let asset_definition_id: AssetDefinitionId = "xor#domain".parse()?; let create_asset = Register::asset_definition(AssetDefinition::quantity(asset_definition_id.clone())).into(); diff --git a/client/tests/integration/extra_functional/unregister_peer.rs b/client/tests/integration/extra_functional/unregister_peer.rs index e73112ae920..b83ac7c1f54 100644 --- a/client/tests/integration/extra_functional/unregister_peer.rs +++ b/client/tests/integration/extra_functional/unregister_peer.rs @@ -108,7 +108,7 @@ fn init() -> Result<( let create_domain = Register::domain(Domain::new("domain".parse()?)); let account_id: AccountId = "account@domain".parse()?; let (public_key, _) = KeyPair::generate().into(); - let create_account = Register::account(Account::new(account_id.clone(), [public_key])); + let create_account = Register::account(Account::new(account_id.clone(), public_key)); let asset_definition_id: AssetDefinitionId = "xor#domain".parse()?; let create_asset = Register::asset_definition(AssetDefinition::quantity(asset_definition_id.clone())); diff --git a/client/tests/integration/permissions.rs b/client/tests/integration/permissions.rs index 0d95e964396..1ceb1569123 100644 --- a/client/tests/integration/permissions.rs +++ b/client/tests/integration/permissions.rs @@ -206,7 +206,7 @@ fn permissions_differ_not_only_by_names() { // Registering mouse let outfit_domain: DomainId = "outfit".parse().unwrap(); let create_outfit_domain = Register::domain(Domain::new(outfit_domain.clone())); - let new_mouse_account = Account::new(mouse_id.clone(), [mouse_keypair.public_key().clone()]); + let new_mouse_account = Account::new(mouse_id.clone(), mouse_keypair.public_key().clone()); client .submit_all_blocking([ InstructionBox::from(create_outfit_domain), @@ -306,7 +306,7 @@ fn stored_vs_granted_token_payload() -> Result<()> { Register::asset_definition(AssetDefinition::store(asset_definition_id.clone())); let mouse_id: AccountId = "mouse@wonderland".parse().expect("Valid"); let mouse_keypair = KeyPair::generate(); - let new_mouse_account = Account::new(mouse_id.clone(), [mouse_keypair.public_key().clone()]); + let new_mouse_account = Account::new(mouse_id.clone(), mouse_keypair.public_key().clone()); let instructions: [InstructionBox; 2] = [ Register::account(new_mouse_account).into(), create_asset.into(), diff --git a/client/tests/integration/queries/account.rs b/client/tests/integration/queries/account.rs index 69d28c66e6f..0e8ac6575d2 100644 --- a/client/tests/integration/queries/account.rs +++ b/client/tests/integration/queries/account.rs @@ -40,7 +40,7 @@ fn find_accounts_with_asset() -> Result<()> { .iter() .skip(1) // Alice has already been registered in genesis .cloned() - .map(|account_id| Register::account(Account::new(account_id, []))) + .map(|account_id| Register::account(Account::new_with_random_signature(account_id))) .collect::>(); test_client.submit_all_blocking(register_accounts)?; diff --git a/client/tests/integration/queries/asset.rs b/client/tests/integration/queries/asset.rs index d987395f76c..982d9873dfe 100644 --- a/client/tests/integration/queries/asset.rs +++ b/client/tests/integration/queries/asset.rs @@ -41,7 +41,7 @@ fn find_asset_total_quantity() -> Result<()> { .skip(1) // Alice has already been registered in genesis .cloned() .zip(keys.iter().map(KeyPair::public_key).cloned()) - .map(|(account_id, public_key)| Register::account(Account::new(account_id, [public_key]))) + .map(|(account_id, public_key)| Register::account(Account::new(account_id, public_key))) .collect::>(); test_client.submit_all_blocking(register_accounts)?; diff --git a/client/tests/integration/roles.rs b/client/tests/integration/roles.rs index f7cc75fdaa4..dabb6405cbb 100644 --- a/client/tests/integration/roles.rs +++ b/client/tests/integration/roles.rs @@ -58,7 +58,7 @@ fn register_and_grant_role_for_metadata_access() -> Result<()> { let mouse_key_pair = KeyPair::generate(); let register_mouse = Register::account(Account::new( mouse_id.clone(), - [mouse_key_pair.public_key().clone()], + mouse_key_pair.public_key().clone(), )); test_client.submit_blocking(register_mouse)?; @@ -110,7 +110,7 @@ fn unregistered_role_removed_from_account() -> Result<()> { let mouse_id: AccountId = "mouse@wonderland".parse().expect("Valid"); // Registering Mouse - let register_mouse = Register::account(Account::new(mouse_id.clone(), [])); + let register_mouse = Register::account(Account::new_with_random_signature(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 19f69f3b86e..024e7048fd7 100644 --- a/client/tests/integration/sorting.rs +++ b/client/tests/integration/sorting.rs @@ -201,7 +201,8 @@ fn correct_sorting_of_entities() { MetadataLimits::new(10, 28), ) .expect("Valid"); - let account = Account::new(account_id.clone(), []).with_metadata(account_metadata.clone()); + let account = Account::new_with_random_signature(account_id.clone()) + .with_metadata(account_metadata.clone()); accounts.push(account_id); metadata_of_accounts.push(account_metadata); @@ -342,7 +343,7 @@ fn sort_only_elements_which_have_sorting_key() -> Result<()> { for i in 0..n { let account_id = AccountId::from_str(&format!("charlie{i}@wonderland")).expect("Valid"); let account = if skip_set.contains(&i) { - let account = Account::new(account_id.clone(), []); + let account = Account::new_with_random_signature(account_id.clone()); accounts_b.push(account_id); account } else { @@ -354,7 +355,8 @@ fn sort_only_elements_which_have_sorting_key() -> Result<()> { MetadataLimits::new(10, 28), ) .expect("Valid"); - let account = Account::new(account_id.clone(), []).with_metadata(account_metadata); + let account = Account::new_with_random_signature(account_id.clone()) + .with_metadata(account_metadata); accounts_a.push(account_id); account }; diff --git a/client/tests/integration/transfer_asset.rs b/client/tests/integration/transfer_asset.rs index 6b3ee6540dc..2c2122f2927 100644 --- a/client/tests/integration/transfer_asset.rs +++ b/client/tests/integration/transfer_asset.rs @@ -184,5 +184,5 @@ fn generate_two_ids() -> (AccountId, AccountId) { fn create_mouse(mouse_id: AccountId) -> Register { let (mouse_public_key, _) = KeyPair::generate().into(); - Register::account(Account::new(mouse_id, [mouse_public_key])) + Register::account(Account::new(mouse_id, mouse_public_key)) } diff --git a/client/tests/integration/triggers/data_trigger.rs b/client/tests/integration/triggers/data_trigger.rs index 2c197c9da18..b8dea755297 100644 --- a/client/tests/integration/triggers/data_trigger.rs +++ b/client/tests/integration/triggers/data_trigger.rs @@ -47,9 +47,8 @@ fn must_execute_both_triggers() -> Result<()> { )); test_client.submit_blocking(register_trigger)?; - test_client.submit_blocking(Register::account(Account::new( + test_client.submit_blocking(Register::account(Account::new_with_random_signature( "bunny@wonderland".parse()?, - [], )))?; test_client.submit_blocking(Register::domain(Domain::new("neverland".parse()?)))?; @@ -68,7 +67,8 @@ fn domain_scoped_trigger_must_be_executed_only_on_events_in_its_domain() -> Resu Register::domain(Domain::new("neverland".parse()?)).into(); let account_id: AccountId = "sapporo@neverland".parse()?; - let create_sapporo_account = Register::account(Account::new(account_id.clone(), [])).into(); + let create_sapporo_account = + Register::account(Account::new_with_random_signature(account_id.clone())).into(); let asset_definition_id: AssetDefinitionId = "sakura#neverland".parse()?; let create_sakura_asset_definition = @@ -107,14 +107,12 @@ fn domain_scoped_trigger_must_be_executed_only_on_events_in_its_domain() -> Resu )); test_client.submit_blocking(register_trigger)?; - test_client.submit_blocking(Register::account(Account::new( + test_client.submit_blocking(Register::account(Account::new_with_random_signature( "asahi@wonderland".parse()?, - [], )))?; - test_client.submit_blocking(Register::account(Account::new( + test_client.submit_blocking(Register::account(Account::new_with_random_signature( "asahi@neverland".parse()?, - [], )))?; let new_value = get_asset_value(&test_client, asset_id)?; diff --git a/client/tests/integration/triggers/time_trigger.rs b/client/tests/integration/triggers/time_trigger.rs index 319467fc24a..e0b4bb19834 100644 --- a/client/tests/integration/triggers/time_trigger.rs +++ b/client/tests/integration/triggers/time_trigger.rs @@ -195,7 +195,7 @@ fn mint_nft_for_every_user_every_1_sec() -> Result<()> { .iter() .skip(1) // Alice has already been registered in genesis .cloned() - .map(|account_id| Register::account(Account::new(account_id, []))) + .map(|account_id| Register::account(Account::new_with_random_signature(account_id))) .collect::>(); test_client.submit_all_blocking(register_accounts)?; diff --git a/client/tests/integration/upgrade.rs b/client/tests/integration/upgrade.rs index b7d0f9a1c04..60a0447a095 100644 --- a/client/tests/integration/upgrade.rs +++ b/client/tests/integration/upgrade.rs @@ -24,7 +24,7 @@ fn executor_upgrade_should_work() -> Result<()> { let admin_id: AccountId = "admin@admin".parse()?; let admin_keypair = KeyPair::generate(); - let admin_account = Account::new(admin_id.clone(), [admin_keypair.public_key().clone()]); + let admin_account = Account::new(admin_id.clone(), admin_keypair.public_key().clone()); let register_admin_account = Register::account(admin_account); client.submit_blocking(register_admin_account)?; diff --git a/client_cli/src/main.rs b/client_cli/src/main.rs index 25e8eaf93c0..8e89a729d9a 100644 --- a/client_cli/src/main.rs +++ b/client_cli/src/main.rs @@ -586,7 +586,7 @@ mod account { fn run(self, context: &mut dyn RunContext) -> Result<()> { let Self { id, key, metadata } = self; let create_account = - iroha_client::data_model::isi::Register::account(Account::new(id, [key])); + iroha_client::data_model::isi::Register::account(Account::new(id, key)); submit([create_account], metadata.load()?, context) .wrap_err("Failed to register account") } diff --git a/configs/swarm/executor.wasm b/configs/swarm/executor.wasm index 135f1021cc0..7e0273e17d5 100644 Binary files a/configs/swarm/executor.wasm and b/configs/swarm/executor.wasm differ diff --git a/core/benches/blocks/common.rs b/core/benches/blocks/common.rs index bfe24efe223..e7712cf1f3c 100644 --- a/core/benches/blocks/common.rs +++ b/core/benches/blocks/common.rs @@ -74,7 +74,7 @@ pub fn populate_wsv( instructions.push(can_unregister_domain.into()); for j in 0..accounts_per_domain { let account_id = construct_account_id(j, domain_id.clone()); - let account = Account::new(account_id.clone(), []); + let account = Account::new_with_random_signature(account_id.clone()); instructions.push(Register::account(account).into()); let can_unregister_account = Grant::permission( PermissionToken::new( @@ -150,7 +150,7 @@ pub fn restore_every_nth( for j in 0..accounts_per_domain { if j % nth == 0 || i % nth == 0 { let account_id = construct_account_id(j, domain_id.clone()); - let account = Account::new(account_id.clone(), []); + let account = Account::new_with_random_signature(account_id.clone()); instructions.push(Register::account(account).into()); } } @@ -181,7 +181,7 @@ pub fn build_wsv( let mut domain = Domain::new(account_id.domain_id.clone()).build(account_id); domain.accounts.insert( account_id.clone(), - Account::new(account_id.clone(), [key_pair.public_key().clone()]).build(account_id), + Account::new(account_id.clone(), key_pair.public_key().clone()).build(account_id), ); let mut wsv = WorldStateView::new(World::with([domain], UniqueVec::new()), kura, query_handle); wsv.config.transaction_limits = TransactionLimits::new(u64::MAX, u64::MAX); diff --git a/core/benches/validation.rs b/core/benches/validation.rs index 037e031cd12..04097530119 100644 --- a/core/benches/validation.rs +++ b/core/benches/validation.rs @@ -34,7 +34,7 @@ fn build_test_transaction(keys: &KeyPair, chain_id: ChainId) -> SignedTransactio domain_name.parse().expect("Valid"), account_name.parse().expect("Valid"), ), - [public_key], + public_key, )) .into(); let asset_definition_id = AssetDefinitionId::new( @@ -69,7 +69,7 @@ fn build_test_and_transient_wsv(keys: KeyPair) -> WorldStateView { Name::from_str(START_ACCOUNT).expect("Valid"), ); let mut domain = Domain::new(domain_id).build(&account_id); - let account = Account::new(account_id.clone(), [public_key]).build(&account_id); + let account = Account::new(account_id.clone(), public_key).build(&account_id); assert!(domain.add_account(account).is_none()); World::with([domain], UniqueVec::new()) }, diff --git a/core/src/block.rs b/core/src/block.rs index b2b0a6bc82d..8fa62f2fdb3 100644 --- a/core/src/block.rs +++ b/core/src/block.rs @@ -699,7 +699,7 @@ mod tests { let alice_id = AccountId::from_str("alice@wonderland").expect("Valid"); let alice_keys = KeyPair::generate(); let account = - Account::new(alice_id.clone(), [alice_keys.public_key().clone()]).build(&alice_id); + Account::new(alice_id.clone(), alice_keys.public_key().clone()).build(&alice_id); let domain_id = DomainId::from_str("wonderland").expect("Valid"); let mut domain = Domain::new(domain_id).build(&alice_id); assert!(domain.add_account(account).is_none()); @@ -742,7 +742,7 @@ mod tests { let alice_id = AccountId::from_str("alice@wonderland").expect("Valid"); let alice_keys = KeyPair::generate(); let account = - Account::new(alice_id.clone(), [alice_keys.public_key().clone()]).build(&alice_id); + Account::new(alice_id.clone(), alice_keys.public_key().clone()).build(&alice_id); let domain_id = DomainId::from_str("wonderland").expect("Valid"); let mut domain = Domain::new(domain_id).build(&alice_id); assert!(domain.add_account(account).is_none()); @@ -808,7 +808,7 @@ mod tests { let alice_id = AccountId::from_str("alice@wonderland").expect("Valid"); let alice_keys = KeyPair::generate(); let account = - Account::new(alice_id.clone(), [alice_keys.public_key().clone()]).build(&alice_id); + Account::new(alice_id.clone(), alice_keys.public_key().clone()).build(&alice_id); let domain_id = DomainId::from_str("wonderland").expect("Valid"); let mut domain = Domain::new(domain_id).build(&alice_id); assert!( diff --git a/core/src/queue.rs b/core/src/queue.rs index 3beab0a9546..b9da0830e1d 100644 --- a/core/src/queue.rs +++ b/core/src/queue.rs @@ -416,7 +416,10 @@ mod tests { let domain_id = DomainId::from_str("wonderland").expect("Valid"); let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); let mut domain = Domain::new(domain_id).build(&account_id); - let account = Account::new(account_id.clone(), signatures).build(&account_id); + let mut signatures = signatures.into_iter(); + let account = Account::new(account_id.clone(), signatures.next().unwrap()) + .with_additional_signatures(signatures) + .build(&account_id); assert!(domain.add_account(account).is_none()); World::with([domain], PeersIds::new()) } @@ -493,11 +496,9 @@ mod tests { let domain_id = DomainId::from_str("wonderland").expect("Valid"); let account_id = AccountId::from_str("alice@wonderland").expect("Valid"); let mut domain = Domain::new(domain_id).build(&account_id); - let mut account = Account::new( - account_id.clone(), - key_pairs.iter().map(KeyPair::public_key).cloned(), - ) - .build(&account_id); + let mut account = Account::new(account_id.clone(), key_pairs[0].public_key().clone()) + .with_additional_signatures([key_pairs[1].public_key().clone()]) + .build(&account_id); account.signature_check_condition = SignatureCheckCondition::all_account_signatures(); assert!(domain.add_account(account).is_none()); let query_handle = LiveQueryStore::test().start(); @@ -887,11 +888,11 @@ mod tests { let mut domain = Domain::new(domain_id).build(&alice_account_id); let alice_account = Account::new( alice_account_id.clone(), - [alice_key_pair.public_key().clone()], + alice_key_pair.public_key().clone(), ) .build(&alice_account_id); let bob_account = - Account::new(bob_account_id.clone(), [bob_key_pair.public_key().clone()]) + Account::new(bob_account_id.clone(), bob_key_pair.public_key().clone()) .build(&bob_account_id); assert!(domain.add_account(alice_account).is_none()); assert!(domain.add_account(bob_account).is_none()); diff --git a/core/src/smartcontracts/isi/mod.rs b/core/src/smartcontracts/isi/mod.rs index ccd65f6d8cb..437ef7c1c91 100644 --- a/core/src/smartcontracts/isi/mod.rs +++ b/core/src/smartcontracts/isi/mod.rs @@ -248,7 +248,7 @@ mod tests { let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland")?; Register::domain(Domain::new(DomainId::from_str("wonderland")?)) .execute(&genesis_account_id, &mut wsv)?; - Register::account(Account::new(account_id, [public_key])) + Register::account(Account::new(account_id, public_key)) .execute(&genesis_account_id, &mut wsv)?; Register::asset_definition(AssetDefinition::store(asset_definition_id)) .execute(&genesis_account_id, &mut wsv)?; @@ -395,8 +395,7 @@ mod tests { // register fake account let (public_key, _) = KeyPair::generate().into(); - let register_account = - Register::account(Account::new(fake_account_id.clone(), [public_key])); + let register_account = Register::account(Account::new(fake_account_id.clone(), public_key)); register_account.execute(&account_id, &mut wsv)?; // register the trigger diff --git a/core/src/smartcontracts/isi/query.rs b/core/src/smartcontracts/isi/query.rs index f7695a93c1c..e43f3354967 100644 --- a/core/src/smartcontracts/isi/query.rs +++ b/core/src/smartcontracts/isi/query.rs @@ -187,7 +187,7 @@ mod tests { let domain_id = DomainId::from_str("wonderland").expect("Valid"); let mut domain = Domain::new(domain_id).build(&ALICE_ID); let account = - Account::new(ALICE_ID.clone(), [ALICE_KEYS.public_key().clone()]).build(&ALICE_ID); + Account::new(ALICE_ID.clone(), ALICE_KEYS.public_key().clone()).build(&ALICE_ID); assert!(domain.add_account(account).is_none()); let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland").expect("Valid"); assert!(domain @@ -201,7 +201,7 @@ mod tests { let mut domain = Domain::new(DomainId::from_str("wonderland").expect("Valid")).build(&ALICE_ID); let mut account = - Account::new(ALICE_ID.clone(), [ALICE_KEYS.public_key().clone()]).build(&ALICE_ID); + Account::new(ALICE_ID.clone(), ALICE_KEYS.public_key().clone()).build(&ALICE_ID); assert!(domain .add_asset_definition( AssetDefinition::quantity(asset_definition_id.clone()).build(&ALICE_ID) @@ -233,7 +233,7 @@ mod tests { )?; let mut domain = Domain::new(DomainId::from_str("wonderland")?).build(&ALICE_ID); - let account = Account::new(ALICE_ID.clone(), [ALICE_KEYS.public_key().clone()]) + let account = Account::new(ALICE_ID.clone(), ALICE_KEYS.public_key().clone()) .with_metadata(metadata) .build(&ALICE_ID); assert!(domain.add_account(account).is_none()); @@ -466,7 +466,7 @@ mod tests { .with_metadata(metadata) .build(&ALICE_ID); let account = - Account::new(ALICE_ID.clone(), [ALICE_KEYS.public_key().clone()]).build(&ALICE_ID); + Account::new(ALICE_ID.clone(), ALICE_KEYS.public_key().clone()).build(&ALICE_ID); 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 ec431e8e458..fa6b0a43f7b 100644 --- a/core/src/smartcontracts/wasm.rs +++ b/core/src/smartcontracts/wasm.rs @@ -1649,7 +1649,7 @@ mod tests { fn world_with_test_account(authority: &AccountId) -> World { let domain_id = authority.domain_id.clone(); let (public_key, _) = KeyPair::generate().into(); - let account = Account::new(authority.clone(), [public_key]).build(authority); + let account = Account::new(authority.clone(), public_key).build(authority); let mut domain = Domain::new(domain_id).build(authority); assert!(domain.add_account(account).is_none()); @@ -1709,7 +1709,7 @@ mod tests { let isi_hex = { let new_authority = AccountId::from_str("mad_hatter@wonderland").expect("Valid"); - let register_isi = Register::account(Account::new(new_authority, [])); + let register_isi = Register::account(Account::new_with_random_signature(new_authority)); encode_hex(InstructionBox::from(register_isi)) }; @@ -1795,7 +1795,7 @@ mod tests { let isi_hex = { let new_authority = AccountId::from_str("mad_hatter@wonderland").expect("Valid"); - let register_isi = Register::account(Account::new(new_authority, [])); + let register_isi = Register::account(Account::new_with_random_signature(new_authority)); encode_hex(InstructionBox::from(register_isi)) }; @@ -1844,7 +1844,7 @@ mod tests { let isi_hex = { let new_authority = AccountId::from_str("mad_hatter@wonderland").expect("Valid"); - let register_isi = Register::account(Account::new(new_authority, [])); + let register_isi = Register::account(Account::new_with_random_signature(new_authority)); encode_hex(InstructionBox::from(register_isi)) }; diff --git a/core/src/sumeragi/main_loop.rs b/core/src/sumeragi/main_loop.rs index b545e281338..2959afa1151 100644 --- a/core/src/sumeragi/main_loop.rs +++ b/core/src/sumeragi/main_loop.rs @@ -1198,7 +1198,7 @@ mod tests { let alice_id: AccountId = "alice@wonderland".parse().expect("Valid"); let alice_keys = KeyPair::generate(); let account = - Account::new(alice_id.clone(), [alice_keys.public_key().clone()]).build(&alice_id); + Account::new(alice_id.clone(), alice_keys.public_key().clone()).build(&alice_id); let domain_id = "wonderland".parse().expect("Valid"); let mut domain = Domain::new(domain_id).build(&alice_id); assert!(domain.add_account(account).is_none()); diff --git a/data_model/Cargo.toml b/data_model/Cargo.toml index 9b80ee2b6fc..a4ce3dd4f8c 100644 --- a/data_model/Cargo.toml +++ b/data_model/Cargo.toml @@ -21,7 +21,7 @@ default = ["std"] # Enable static linkage of the rust standard library. # Disabled for WASM interoperability, to reduce the binary size. # Please refer to https://docs.rust-embedded.org/book/intro/no-std.html -std = ["iroha_macro/std", "iroha_version/std", "iroha_crypto/std", "iroha_primitives/std", "thiserror", "displaydoc/std", "strum/std", "once_cell"] +std = ["rand", "iroha_macro/std", "iroha_version/std", "iroha_crypto/std", "iroha_primitives/std", "thiserror", "displaydoc/std", "strum/std", "once_cell"] # Enable API for HTTP requests. Should be activated for HTTP clients http = ["std", "warp", "iroha_version/http"] # Replace structures and methods with FFI equivalents to facilitate dynamic linkage (mainly used in smartcontracts) @@ -32,6 +32,9 @@ ffi_export = ["std", "iroha_ffi", "iroha_primitives/ffi_export", "iroha_crypto/f # Expose API for mutating structures (Internal use only) transparent_api = [] +# Activate key generation from random bytes +rand = ["iroha_crypto/rand"] + [dependencies] iroha_primitives = { workspace = true } iroha_data_model_derive = { workspace = true } diff --git a/data_model/src/account.rs b/data_model/src/account.rs index 59ad7b0a4d9..4740719a06b 100644 --- a/data_model/src/account.rs +++ b/data_model/src/account.rs @@ -109,15 +109,17 @@ pub mod model { /// Builder which should be submitted in a transaction to create a new [`Account`] #[derive( - DebugCustom, Display, Clone, IdEqOrdHash, Decode, Encode, Serialize, Deserialize, IntoSchema, + DebugCustom, Display, Clone, IdEqOrdHash, Encode, Serialize, Deserialize, IntoSchema, )] #[display(fmt = "[{id}]")] #[debug(fmt = "[{id:?}] {{ signatories: {signatories:?}, metadata: {metadata} }}")] #[ffi_type] + #[serde(try_from = "NewAccountCandidate")] pub struct NewAccount { /// Identification pub id: AccountId, /// Signatories, i.e. signatures attached to this message. + /// Cannot be empty, guaranteed by constructors. pub signatories: Signatories, /// Metadata that should be submitted with the builder pub metadata: Metadata, @@ -149,14 +151,11 @@ pub mod model { } impl Account { - /// Construct builder for [`Account`] identifiable by [`Id`] containing the given signatories. + /// Construct builder for [`Account`] identifiable by [`Id`] containing the given signature. #[inline] #[must_use] - pub fn new( - id: AccountId, - signatories: impl IntoIterator, - ) -> ::With { - ::With::new(id, signatories) + pub fn new(id: AccountId, signature: PublicKey) -> ::With { + ::With::new(id, signature) } /// Get an iterator over [`signatories`](PublicKey) of the `Account` @@ -186,6 +185,19 @@ impl Account { #[cfg(feature = "transparent_api")] impl Account { + /// Construct builder for [`Account`] identifiable by [`Id`] containing random signature. + /// + /// Without the use of [`with_additional_signatures()`](NewAccount::with_additional_signatures) + /// this will make impossible to sign anything from behalf of this account. + /// + /// Usable for tests where there is no need to use the account directly. + #[inline] + #[must_use] + #[cfg(feature = "rand")] + pub fn new_with_random_signature(id: AccountId) -> ::With { + ::With::new(id, iroha_crypto::KeyPair::generate().public_key().clone()) + } + /// Add [`Asset`] into the [`Account`] returning previous asset stored under the same id #[inline] pub fn add_asset(&mut self, asset: Asset) -> Option { @@ -214,15 +226,27 @@ impl Account { } impl NewAccount { - fn new(id: AccountId, signatories: impl IntoIterator) -> Self { + fn new(id: AccountId, signature: PublicKey) -> Self { Self { id, - signatories: signatories.into_iter().collect(), + signatories: Signatories::from([signature]), metadata: Metadata::default(), } } + /// Add additional signatures to account. + #[inline] + #[must_use] + pub fn with_additional_signatures( + mut self, + signatures: impl IntoIterator, + ) -> Self { + self.signatories.extend(signatures); + self + } + /// Add [`Metadata`] to the account replacing any previously defined metadata + #[inline] #[must_use] pub fn with_metadata(mut self, metadata: Metadata) -> Self { self.metadata = metadata; @@ -236,6 +260,39 @@ impl HasMetadata for NewAccount { } } +/// [`NewAccount`] candidate used for deserialization checks +#[derive(Decode, Deserialize)] +struct NewAccountCandidate { + id: AccountId, + signatories: Signatories, + metadata: Metadata, +} + +impl TryFrom for NewAccount { + type Error = &'static str; + + fn try_from(candidate: NewAccountCandidate) -> Result { + if candidate.signatories.is_empty() { + return Err("Signatures cannot be empty"); + } + + Ok(Self { + id: candidate.id, + signatories: candidate.signatories, + metadata: candidate.metadata, + }) + } +} + +impl Decode for NewAccount { + fn decode( + input: &mut I, + ) -> Result { + let candidate = NewAccountCandidate::decode(input)?; + Self::try_from(candidate).map_err(Into::into) + } +} + impl HasMetadata for Account { fn metadata(&self) -> &Metadata { &self.metadata diff --git a/data_model/src/predicate.rs b/data_model/src/predicate.rs index e50157fdaf7..7020cac2a96 100644 --- a/data_model/src/predicate.rs +++ b/data_model/src/predicate.rs @@ -1169,7 +1169,9 @@ pub mod value { )))); assert!( pred.applies(&Value::Identifiable(IdentifiableBox::NewAccount( - Account::new("alice@wonderland".parse().expect("Valid"), []) + Account::new_with_random_signature( + "alice@wonderland".parse().expect("Valid") + ) ))) ); assert!(!pred.applies(&Value::Name("alice".parse().expect("Valid")))); diff --git a/genesis/src/lib.rs b/genesis/src/lib.rs index b9eab5b2b2e..860d2101dc5 100644 --- a/genesis/src/lib.rs +++ b/genesis/src/lib.rs @@ -308,7 +308,7 @@ impl RawGenesisDomainBuilder { let account_id = AccountId::new(self.domain_id.clone(), account_name); self.transaction .isi - .push(Register::account(Account::new(account_id, [])).into()); + .push(Register::account(Account::new_with_random_signature(account_id)).into()); self } @@ -326,7 +326,7 @@ impl RawGenesisDomainBuilder { ) -> Self { let account_id = AccountId::new(self.domain_id.clone(), account_name); let register = - Register::account(Account::new(account_id, [public_key]).with_metadata(metadata)); + Register::account(Account::new(account_id, public_key).with_metadata(metadata)); self.transaction.isi.push(register.into()); self } @@ -406,18 +406,18 @@ mod tests { ); assert_eq!( finished_genesis_block.transactions[0].isi[1], - Register::account(Account::new( - AccountId::new(domain_id.clone(), "alice".parse().unwrap()), - [] - )) + Register::account(Account::new_with_random_signature(AccountId::new( + domain_id.clone(), + "alice".parse().unwrap() + ))) .into() ); assert_eq!( finished_genesis_block.transactions[0].isi[2], - Register::account(Account::new( - AccountId::new(domain_id, "bob".parse().unwrap()), - [] - )) + Register::account(Account::new_with_random_signature(AccountId::new( + domain_id, + "bob".parse().unwrap() + ))) .into() ); } @@ -429,10 +429,10 @@ mod tests { ); assert_eq!( finished_genesis_block.transactions[0].isi[4], - Register::account(Account::new( - AccountId::new(domain_id, "Cheshire_Cat".parse().unwrap()), - [] - )) + Register::account(Account::new_with_random_signature(AccountId::new( + domain_id, + "Cheshire_Cat".parse().unwrap() + ),)) .into() ); } @@ -446,7 +446,7 @@ mod tests { finished_genesis_block.transactions[0].isi[6], Register::account(Account::new( AccountId::new(domain_id, "Mad_Hatter".parse().unwrap()), - [public_key.parse().unwrap()], + public_key.parse().unwrap(), )) .into() ); diff --git a/smart_contract/src/lib.rs b/smart_contract/src/lib.rs index 005b2c69338..a324518d56a 100644 --- a/smart_contract/src/lib.rs +++ b/smart_contract/src/lib.rs @@ -472,7 +472,7 @@ mod tests { fn get_test_instruction() -> InstructionBox { let new_account_id = "mad_hatter@wonderland".parse().expect("Valid"); - let register_isi = Register::account(Account::new(new_account_id, [])); + let register_isi = Register::account(Account::new_with_random_signature(new_account_id)); register_isi.into() } diff --git a/tools/parity_scale_decoder/Cargo.toml b/tools/parity_scale_decoder/Cargo.toml index e2cb948ff7a..37087501892 100644 --- a/tools/parity_scale_decoder/Cargo.toml +++ b/tools/parity_scale_decoder/Cargo.toml @@ -33,5 +33,6 @@ colored = "2.0.4" iroha_data_model = { workspace = true } parity-scale-codec = { workspace = true } -serde_json = { workspace = true } +serde_json = { workspace = true, features = ["std"]} serde = { workspace = true } +eyre = { workspace = true } diff --git a/tools/parity_scale_decoder/build.rs b/tools/parity_scale_decoder/build.rs index 49223203f69..00391f5e58e 100644 --- a/tools/parity_scale_decoder/build.rs +++ b/tools/parity_scale_decoder/build.rs @@ -1,7 +1,8 @@ //! Build script that auto-updates sample binaries from sources. -use std::{fs, io::Result, path::PathBuf}; +use std::{fs, path::PathBuf}; +use eyre::Result; use iroha_data_model::{account::NewAccount, domain::NewDomain, prelude::*}; use parity_scale_codec::Encode; use serde::de::DeserializeOwned; diff --git a/tools/parity_scale_decoder/samples/account.bin b/tools/parity_scale_decoder/samples/account.bin index 04aea960c0e..c0ac2716337 100644 Binary files a/tools/parity_scale_decoder/samples/account.bin and b/tools/parity_scale_decoder/samples/account.bin differ diff --git a/tools/parity_scale_decoder/samples/account.json b/tools/parity_scale_decoder/samples/account.json index 08c2536561c..7bb4321521b 100644 --- a/tools/parity_scale_decoder/samples/account.json +++ b/tools/parity_scale_decoder/samples/account.json @@ -1,6 +1,8 @@ { "id": "alice@wonderland", - "signatories": [], + "signatories": [ + "ed0120EDF6D7B52C7032D03AEC696F2068BD53101528F3C7B6081BFF05A1662D7FC245" + ], "metadata": { "hat": { "Name": "white" diff --git a/tools/parity_scale_decoder/src/main.rs b/tools/parity_scale_decoder/src/main.rs index 6a60e0396ad..b01d9e9b3af 100644 --- a/tools/parity_scale_decoder/src/main.rs +++ b/tools/parity_scale_decoder/src/main.rs @@ -219,13 +219,17 @@ mod tests { let mut metadata = Metadata::new(); metadata .insert_with_limits( - "hat".parse().expect("Valid"), - Value::Name("white".parse().expect("Valid")), + "hat".parse().unwrap(), + Value::Name("white".parse().unwrap()), limits, ) .expect("Valid"); + let signature = PublicKey::from_str( + "ed0120EDF6D7B52C7032D03AEC696F2068BD53101528F3C7B6081BFF05A1662D7FC245", + ) + .unwrap(); let account = - Account::new("alice@wonderland".parse().expect("Valid"), []).with_metadata(metadata); + Account::new("alice@wonderland".parse().unwrap(), signature).with_metadata(metadata); decode_sample("account.bin", String::from("NewAccount"), &account); }