diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 59cb2d91821..8c61027bcba 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -260,6 +260,7 @@ impl Iroha { let world = World::with( [genesis_domain(config.genesis.public_key.clone())], [genesis_account(config.genesis.public_key.clone())], + [], config .sumeragi .trusted_peers diff --git a/configs/swarm/executor.wasm b/configs/swarm/executor.wasm index 26823f64271..e23238a47bb 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 e964bae048b..96c408281a5 100644 --- a/core/benches/blocks/common.rs +++ b/core/benches/blocks/common.rs @@ -188,6 +188,7 @@ pub fn build_state(rt: &tokio::runtime::Handle, account_id: &AccountId) -> State World::with( [domain], [Account::new(account_id.clone()).build(account_id)], + [], UniqueVec::new(), ), kura, diff --git a/core/src/block.rs b/core/src/block.rs index 05169d30d8b..e2499543615 100644 --- a/core/src/block.rs +++ b/core/src/block.rs @@ -997,7 +997,7 @@ mod tests { let account = Account::new(alice_id.clone()).build(&alice_id); let domain_id = DomainId::from_str("wonderland").expect("Valid"); let domain = Domain::new(domain_id).build(&alice_id); - let world = World::with([domain], [account], UniqueVec::new()); + let world = World::with([domain], [account], [], UniqueVec::new()); let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); let state = State::new(world, kura, query_handle); @@ -1053,7 +1053,7 @@ mod tests { let account = Account::new(alice_id.clone()).build(&alice_id); let domain_id = DomainId::from_str("wonderland").expect("Valid"); let domain = Domain::new(domain_id).build(&alice_id); - let world = World::with([domain], [account], UniqueVec::new()); + let world = World::with([domain], [account], [], UniqueVec::new()); let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); let state = State::new(world, kura, query_handle); @@ -1127,7 +1127,7 @@ mod tests { let account = Account::new(alice_id.clone()).build(&alice_id); let domain_id = DomainId::from_str("wonderland").expect("Valid"); let domain = Domain::new(domain_id).build(&alice_id); - let world = World::with([domain], [account], UniqueVec::new()); + let world = World::with([domain], [account], [], UniqueVec::new()); let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); let state = State::new(world, kura, query_handle); @@ -1205,7 +1205,12 @@ mod tests { Domain::new(GENESIS_DOMAIN_ID.clone()).build(&genesis_correct_account_id); let genesis_wrong_account = Account::new(genesis_wrong_account_id.clone()).build(&genesis_wrong_account_id); - let world = World::with([genesis_domain], [genesis_wrong_account], UniqueVec::new()); + let world = World::with( + [genesis_domain], + [genesis_wrong_account], + [], + UniqueVec::new(), + ); let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); let state = State::new(world, kura, query_handle); diff --git a/core/src/queue.rs b/core/src/queue.rs index 1d8d1985ab1..17218d9de33 100644 --- a/core/src/queue.rs +++ b/core/src/queue.rs @@ -439,7 +439,7 @@ pub mod tests { let (account_id, _account_keypair) = gen_account_in("wonderland"); let domain = Domain::new(domain_id).build(&account_id); let account = Account::new(account_id.clone()).build(&account_id); - World::with([domain], [account], PeersIds::new()) + World::with([domain], [account], [], PeersIds::new()) } fn config_factory() -> Config { @@ -840,7 +840,7 @@ pub mod tests { let domain = Domain::new(domain_id).build(&alice_id); let alice_account = Account::new(alice_id.clone()).build(&alice_id); let bob_account = Account::new(bob_id.clone()).build(&bob_id); - World::with([domain], [alice_account, bob_account], PeersIds::new()) + World::with([domain], [alice_account, bob_account], [], PeersIds::new()) }; let query_handle = LiveQueryStore::test().start(); let state = State::new(world, kura, query_handle); diff --git a/core/src/smartcontracts/isi/account.rs b/core/src/smartcontracts/isi/account.rs index 4278dd67229..2ba18eea0e0 100644 --- a/core/src/smartcontracts/isi/account.rs +++ b/core/src/smartcontracts/isi/account.rs @@ -97,12 +97,9 @@ pub mod isi { let asset = state_transaction .world - .account_mut(&asset_id.account) - .and_then(|account| { - account - .remove_asset(&asset_id.definition) - .ok_or_else(|| FindError::Asset(asset_id)) - })?; + .assets + .remove(asset_id.clone()) + .ok_or_else(|| FindError::Asset(asset_id))?; match asset.value { AssetValue::Numeric(increment) => { @@ -586,7 +583,16 @@ pub mod query { state_ro .world() .accounts_iter() - .filter(move |account| account.assets.contains_key(&asset_definition_id)) + .filter(move |account| { + state_ro + .world() + .assets() + .get(&AssetId::new( + asset_definition_id.clone(), + account.id().clone(), + )) + .is_some() + }) .cloned(), )) } diff --git a/core/src/smartcontracts/isi/asset.rs b/core/src/smartcontracts/isi/asset.rs index d3221810474..df8d3c0f321 100644 --- a/core/src/smartcontracts/isi/asset.rs +++ b/core/src/smartcontracts/isi/asset.rs @@ -141,19 +141,18 @@ pub mod isi { let asset = state_transaction .world - .account_mut(&asset_id.account) - .and_then(|account| { - account - .remove_asset(&asset_id.definition) - .ok_or_else(|| FindError::Asset(asset_id.clone())) - })?; + .assets + .get_mut(&asset_id) + .ok_or_else(|| FindError::Asset(asset_id.clone()))?; let destination_store = { + let value = asset.value.clone(); + let destination_id = AssetId::new(asset_id.definition.clone(), self.destination.clone()); let destination_store_asset = state_transaction .world - .asset_or_insert(destination_id.clone(), asset.value)?; + .asset_or_insert(destination_id.clone(), value)?; destination_store_asset.clone() }; @@ -230,10 +229,10 @@ pub mod isi { )?; assert_numeric_spec(&self.object, &asset_definition)?; - let account = state_transaction.world.account_mut(&asset_id.account)?; - let asset = account + let asset = state_transaction + .world .assets - .get_mut(&asset_id.definition) + .get_mut(&asset_id) .ok_or_else(|| FindError::Asset(asset_id.clone()))?; let AssetValue::Numeric(quantity) = &mut asset.value else { return Err(Error::Conversion("Expected numeric asset type".to_owned())); @@ -243,7 +242,11 @@ pub mod isi { .ok_or(MathError::NotEnoughQuantity)?; if asset.value.is_zero_value() { - assert!(account.remove_asset(&asset_id.definition).is_some()); + assert!(state_transaction + .world + .assets + .remove(asset_id.clone()) + .is_some()); } #[allow(clippy::float_arithmetic)] @@ -286,10 +289,10 @@ pub mod isi { assert_numeric_spec(&self.object, &asset_definition)?; { - let account = state_transaction.world.account_mut(&source_id.account)?; - let asset = account + let asset = state_transaction + .world .assets - .get_mut(&source_id.definition) + .get_mut(&source_id) .ok_or_else(|| FindError::Asset(source_id.clone()))?; let AssetValue::Numeric(quantity) = &mut asset.value else { return Err(Error::Conversion("Expected numeric asset type".to_owned())); @@ -298,7 +301,11 @@ pub mod isi { .checked_sub(self.object) .ok_or(MathError::NotEnoughQuantity)?; if asset.value.is_zero_value() { - assert!(account.remove_asset(&source_id.definition).is_some()); + assert!(state_transaction + .world + .assets + .remove(source_id.clone()) + .is_some()); } } @@ -430,13 +437,7 @@ pub mod query { &self, state_ro: &'state impl StateReadOnly, ) -> Result + 'state>, Error> { - Ok(Box::new( - state_ro - .world() - .accounts_iter() - .flat_map(|account| account.assets.values()) - .cloned(), - )) + Ok(Box::new(state_ro.world().assets_iter().cloned())) } } @@ -446,13 +447,7 @@ pub mod query { &self, state_ro: &'state impl StateReadOnly, ) -> Result + 'state>, Error> { - Ok(Box::new( - state_ro - .world() - .domains_iter() - .flat_map(|domain| domain.asset_definitions.values()) - .cloned(), - )) + Ok(Box::new(state_ro.world().asset_definitions_iter().cloned())) } } @@ -493,15 +488,8 @@ pub mod query { Ok(Box::new( state_ro .world() - .accounts_iter() - .flat_map(move |account| { - let name = name.clone(); - - account - .assets - .values() - .filter(move |asset| asset.id().definition.name == name) - }) + .assets_iter() + .filter(move |asset| asset.id().definition.name == name) .cloned(), )) } @@ -513,9 +501,16 @@ pub mod query { &self, state_ro: &'state impl StateReadOnly, ) -> Result + 'state>, Error> { - let id = &self.account; + let id = self.account.clone(); iroha_logger::trace!(%id); - Ok(Box::new(state_ro.world().account_assets(id)?.cloned())) + let _ = state_ro.world().map_account(&id, |_| ())?; + Ok(Box::new( + state_ro + .world() + .assets_iter() + .filter(move |asset| asset.id().account == id) + .cloned(), + )) } } @@ -530,15 +525,8 @@ pub mod query { Ok(Box::new( state_ro .world() - .accounts_iter() - .flat_map(move |account| { - let id = id.clone(); - - account - .assets - .values() - .filter(move |asset| asset.id().definition == id) - }) + .assets_iter() + .filter(move |asset| asset.id().definition == id) .cloned(), )) } @@ -550,13 +538,13 @@ pub mod query { &self, state_ro: &'state impl StateReadOnly, ) -> Result + 'state>, Error> { - let id = &self.domain; + let id = self.domain.clone(); iroha_logger::trace!(%id); Ok(Box::new( state_ro .world() - .accounts_in_domain_iter(id) - .flat_map(|account| account.assets.values()) + .assets_iter() + .filter(move |asset| asset.id().account.domain() == &id) .cloned(), )) } @@ -570,24 +558,16 @@ pub mod query { ) -> Result + 'state>, Error> { let domain_id = self.domain.clone(); let asset_definition_id = self.asset_definition.clone(); - let domain = state_ro.world().domain(&domain_id)?; - let _definition = domain - .asset_definitions - .get(&asset_definition_id) - .ok_or_else(|| FindError::AssetDefinition(asset_definition_id.clone()))?; + let _ = state_ro.world().domain(&domain_id)?; + let _ = state_ro.world().asset_definition(&asset_definition_id)?; iroha_logger::trace!(%domain_id, %asset_definition_id); Ok(Box::new( state_ro .world() - .accounts_in_domain_iter(&domain_id) - .flat_map(move |account| { - let domain_id = domain_id.clone(); - let asset_definition_id = asset_definition_id.clone(); - - account.assets.values().filter(move |asset| { - asset.id().account.domain == domain_id - && asset.id().definition == asset_definition_id - }) + .assets_iter() + .filter(move |asset| { + asset.id().definition == asset_definition_id + && asset.id().account.domain() == &domain_id }) .cloned(), )) diff --git a/core/src/smartcontracts/isi/domain.rs b/core/src/smartcontracts/isi/domain.rs index 590059d3aed..cb01fa8d5f7 100644 --- a/core/src/smartcontracts/isi/domain.rs +++ b/core/src/smartcontracts/isi/domain.rs @@ -1,11 +1,7 @@ //! This module contains [`Domain`] structure and related implementations and trait implementations. use eyre::Result; -use iroha_data_model::{ - asset::{AssetDefinitionsMap, AssetTotalQuantityMap}, - prelude::*, - query::error::FindError, -}; +use iroha_data_model::{prelude::*, query::error::FindError}; use iroha_telemetry::metrics; use super::super::isi::prelude::*; @@ -18,8 +14,6 @@ impl Registrable for iroha_data_model::domain::NewDomain { fn build(self, authority: &AccountId) -> Self::Target { Self::Target { id: self.id, - asset_definitions: AssetDefinitionsMap::default(), - asset_total_quantities: AssetTotalQuantityMap::default(), metadata: self.metadata, logo: self.logo, owned_by: authority.clone(), @@ -109,6 +103,15 @@ pub mod isi { state_transaction.world.remove_account_roles(&account_id); + let remove_assets: Vec = state_transaction + .world + .assets_in_account_iter(&account_id) + .map(|ad| ad.id().clone()) + .collect(); + for asset_id in remove_assets { + state_transaction.world.assets.remove(asset_id); + } + if state_transaction .world .accounts @@ -136,20 +139,30 @@ pub mod isi { let asset_definition = self.object.build(authority); let asset_definition_id = asset_definition.id().clone(); - let domain = state_transaction + if state_transaction .world - .domain_mut(&asset_definition_id.domain)?; - if domain.asset_definitions.contains_key(&asset_definition_id) { + .asset_definition(&asset_definition_id) + .is_ok() + { return Err(RepetitionError { instruction: InstructionType::Register, id: IdBox::AssetDefinitionId(asset_definition_id), } .into()); } + let _ = state_transaction + .world + .domain(&asset_definition_id.domain)?; - domain.add_asset_total_quantity(asset_definition_id, Numeric::ZERO); + state_transaction + .world + .asset_total_quantities + .insert(asset_definition_id.clone(), Numeric::ZERO); - domain.add_asset_definition(asset_definition.clone()); + state_transaction + .world + .asset_definitions + .insert(asset_definition_id.clone(), asset_definition.clone()); state_transaction .world @@ -171,50 +184,49 @@ pub mod isi { let asset_definition_id = self.object; let mut assets_to_remove = Vec::new(); - for (_, account) in state_transaction.world.accounts.iter() { - assets_to_remove.extend( - account - .assets - .values() - .filter_map(|asset| { - if asset.id().definition == asset_definition_id { - return Some(asset.id()); - } - - None - }) - .cloned(), - ) - } + assets_to_remove.extend( + state_transaction + .world + .assets + .iter() + .filter(|(asset_id, _)| asset_id.definition == asset_definition_id) + .map(|(asset_id, _)| asset_id) + .cloned(), + ); let mut events = Vec::with_capacity(assets_to_remove.len() + 1); for asset_id in assets_to_remove { if state_transaction .world - .account_mut(&asset_id.account)? - .remove_asset(&asset_id.definition) + .assets + .remove(asset_id.clone()) .is_none() { error!(%asset_id, "asset not found. This is a bug"); } - events.push(AccountEvent::Asset(AssetEvent::Deleted(asset_id)).into()); + events.push(AssetEvent::Deleted(asset_id).into()); } - let domain = state_transaction + if state_transaction .world - .domain_mut(&asset_definition_id.domain)?; - if domain - .remove_asset_definition(&asset_definition_id) + .asset_definitions + .remove(asset_definition_id.clone()) .is_none() { return Err(FindError::AssetDefinition(asset_definition_id).into()); } + let _ = state_transaction + .world + .domain(&asset_definition_id.domain)?; - domain.remove_asset_total_quantity(&asset_definition_id); + state_transaction + .world + .asset_total_quantities + .remove(asset_definition_id.clone()); - events.push(DataEvent::from(DomainEvent::AssetDefinition( - AssetDefinitionEvent::Deleted(asset_definition_id), + events.push(DataEvent::from(AssetDefinitionEvent::Deleted( + asset_definition_id, ))); state_transaction.world.emit_events(events); diff --git a/core/src/smartcontracts/isi/mod.rs b/core/src/smartcontracts/isi/mod.rs index 7466ebdbe4d..a57ec6bd3c9 100644 --- a/core/src/smartcontracts/isi/mod.rs +++ b/core/src/smartcontracts/isi/mod.rs @@ -244,7 +244,7 @@ mod tests { }; fn state_with_test_domains(kura: &Arc) -> Result { - let world = World::with([], [], PeersIds::new()); + let world = World::with([], [], [], PeersIds::new()); let query_handle = LiveQueryStore::test().start(); let state = State::new(world, kura.clone(), query_handle); let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland")?; diff --git a/core/src/smartcontracts/isi/query.rs b/core/src/smartcontracts/isi/query.rs index 395e9618e74..557db5644f7 100644 --- a/core/src/smartcontracts/isi/query.rs +++ b/core/src/smartcontracts/isi/query.rs @@ -312,25 +312,19 @@ mod tests { fn world_with_test_domains() -> World { let domain_id = DomainId::from_str("wonderland").expect("Valid"); - let mut domain = Domain::new(domain_id).build(&ALICE_ID); + let domain = Domain::new(domain_id).build(&ALICE_ID); let account = Account::new(ALICE_ID.clone()).build(&ALICE_ID); let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland").expect("Valid"); - assert!(domain - .add_asset_definition(AssetDefinition::numeric(asset_definition_id).build(&ALICE_ID)) - .is_none()); - World::with([domain], [account], PeersIds::new()) + let asset_definition = AssetDefinition::numeric(asset_definition_id).build(&ALICE_ID); + World::with([domain], [account], [asset_definition], PeersIds::new()) } 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(&ALICE_ID); - let mut account = Account::new(ALICE_ID.clone()).build(&ALICE_ID); - assert!(domain - .add_asset_definition( - AssetDefinition::numeric(asset_definition_id.clone()).build(&ALICE_ID) - ) - .is_none()); + let domain = Domain::new(DomainId::from_str("wonderland").expect("Valid")).build(&ALICE_ID); + let account = Account::new(ALICE_ID.clone()).build(&ALICE_ID); + let asset_definition = + AssetDefinition::numeric(asset_definition_id.clone()).build(&ALICE_ID); let mut store = Metadata::default(); store.insert( @@ -340,23 +334,31 @@ mod tests { let asset_id = AssetId::new(asset_definition_id, account.id().clone()); let asset = Asset::new(asset_id, AssetValue::Store(store)); - assert!(account.add_asset(asset).is_none()); - World::with([domain], [account], PeersIds::new()) + World::with_assets( + [domain], + [account], + [asset_definition], + [asset], + PeersIds::new(), + ) } fn world_with_test_account_with_metadata() -> Result { let mut metadata = Metadata::default(); metadata.insert(Name::from_str("Bytes")?, vec![1_u32, 2_u32, 3_u32]); - let mut domain = Domain::new(DomainId::from_str("wonderland")?).build(&ALICE_ID); + let domain = Domain::new(DomainId::from_str("wonderland")?).build(&ALICE_ID); let account = Account::new(ALICE_ID.clone()) .with_metadata(metadata) .build(&ALICE_ID); let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland").expect("Valid"); - assert!(domain - .add_asset_definition(AssetDefinition::numeric(asset_definition_id).build(&ALICE_ID)) - .is_none()); - Ok(World::with([domain], [account], PeersIds::new())) + let asset_definition = AssetDefinition::numeric(asset_definition_id).build(&ALICE_ID); + Ok(World::with( + [domain], + [account], + [asset_definition], + PeersIds::new(), + )) } fn state_with_test_blocks_and_transactions( @@ -594,19 +596,15 @@ mod tests { let state = { let mut metadata = Metadata::default(); metadata.insert(Name::from_str("Bytes")?, vec![1_u32, 2_u32, 3_u32]); - let mut domain = Domain::new(DomainId::from_str("wonderland")?) + let domain = Domain::new(DomainId::from_str("wonderland")?) .with_metadata(metadata) .build(&ALICE_ID); let account = Account::new(ALICE_ID.clone()).build(&ALICE_ID); let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland")?; - assert!(domain - .add_asset_definition( - AssetDefinition::numeric(asset_definition_id).build(&ALICE_ID) - ) - .is_none()); + let asset_definition = AssetDefinition::numeric(asset_definition_id).build(&ALICE_ID); let query_handle = LiveQueryStore::test().start(); State::new( - World::with([domain], [account], PeersIds::new()), + World::with([domain], [account], [asset_definition], PeersIds::new()), kura, query_handle, ) diff --git a/core/src/smartcontracts/isi/world.rs b/core/src/smartcontracts/isi/world.rs index ff65fdee954..bb348f84475 100644 --- a/core/src/smartcontracts/isi/world.rs +++ b/core/src/smartcontracts/isi/world.rs @@ -147,9 +147,34 @@ pub mod isi { state_transaction.world.remove_account_roles(&account); + let remove_assets: Vec = state_transaction + .world + .assets_in_account_iter(&account) + .map(|ad| ad.id().clone()) + .collect(); + for asset_id in remove_assets { + state_transaction.world.assets.remove(asset_id); + } + state_transaction.world.accounts.remove(account); } + let remove_asset_definitions: Vec = state_transaction + .world + .asset_definitions_in_domain_iter(&domain_id) + .map(|ad| ad.id().clone()) + .collect(); + for asset_definition_id in remove_asset_definitions { + state_transaction + .world + .asset_definitions + .remove(asset_definition_id.clone()); + state_transaction + .world + .asset_total_quantities + .remove(asset_definition_id); + } + if state_transaction .world .domains diff --git a/core/src/smartcontracts/wasm.rs b/core/src/smartcontracts/wasm.rs index c113f9a8562..215d6d9a40b 100644 --- a/core/src/smartcontracts/wasm.rs +++ b/core/src/smartcontracts/wasm.rs @@ -1721,7 +1721,7 @@ mod tests { let account = Account::new(authority.clone()).build(authority); let domain = Domain::new(domain_id).build(authority); - World::with([domain], [account], PeersIds::new()) + World::with([domain], [account], [], PeersIds::new()) } fn memory_and_alloc(isi_hex: &str) -> String { diff --git a/core/src/state.rs b/core/src/state.rs index 7335d11de48..17aa9bd762f 100644 --- a/core/src/state.rs +++ b/core/src/state.rs @@ -25,7 +25,7 @@ use iroha_data_model::{ use iroha_logger::prelude::*; use iroha_primitives::{must_use::MustUse, numeric::Numeric, small::SmallVec}; use parking_lot::Mutex; -use range_bounds::{AccountByDomainBounds, AsAccountIdDomainCompare, RoleIdByAccountBounds}; +use range_bounds::*; use serde::{ de::{DeserializeSeed, MapAccess, Visitor}, Deserializer, Serialize, @@ -71,6 +71,12 @@ pub struct World { pub(crate) domains: Storage, /// Registered accounts. pub(crate) accounts: Storage, + /// Registered asset definitions. + pub(crate) asset_definitions: Storage, + /// Registered asset definition total amounts. + pub(crate) asset_total_quantities: Storage, + /// Registered assets. + pub(crate) assets: Storage, /// Roles. [`Role`] pairs. pub(crate) roles: Storage, /// Permission tokens of an account. @@ -95,6 +101,12 @@ pub struct WorldBlock<'world> { pub(crate) domains: StorageBlock<'world, DomainId, Domain>, /// Registered accounts. pub(crate) accounts: StorageBlock<'world, AccountId, Account>, + /// Registered asset definitions. + pub(crate) asset_definitions: StorageBlock<'world, AssetDefinitionId, AssetDefinition>, + /// Registered asset definition total amounts. + pub(crate) asset_total_quantities: StorageBlock<'world, AssetDefinitionId, Numeric>, + /// Registered assets. + pub(crate) assets: StorageBlock<'world, AssetId, Asset>, /// Roles. [`Role`] pairs. pub(crate) roles: StorageBlock<'world, RoleId, Role>, /// Permission tokens of an account. @@ -121,6 +133,14 @@ pub struct WorldTransaction<'block, 'world> { pub(crate) domains: StorageTransaction<'block, 'world, DomainId, Domain>, /// Registered accounts. pub(crate) accounts: StorageTransaction<'block, 'world, AccountId, Account>, + /// Registered asset definitions. + pub(crate) asset_definitions: + StorageTransaction<'block, 'world, AssetDefinitionId, AssetDefinition>, + /// Registered asset definition total amounts. + pub(crate) asset_total_quantities: + StorageTransaction<'block, 'world, AssetDefinitionId, Numeric>, + /// Registered assets. + pub(crate) assets: StorageTransaction<'block, 'world, AssetId, Asset>, /// Roles. [`Role`] pairs. pub(crate) roles: StorageTransaction<'block, 'world, RoleId, Role>, /// Permission tokens of an account. @@ -155,6 +175,12 @@ pub struct WorldView<'world> { pub(crate) domains: StorageView<'world, DomainId, Domain>, /// Registered accounts. pub(crate) accounts: StorageView<'world, AccountId, Account>, + /// Registered asset definitions. + pub(crate) asset_definitions: StorageView<'world, AssetDefinitionId, AssetDefinition>, + /// Registered asset definition total amounts. + pub(crate) asset_total_quantities: StorageView<'world, AssetDefinitionId, Numeric>, + /// Registered assets. + pub(crate) assets: StorageView<'world, AssetId, Asset>, /// Roles. [`Role`] pairs. pub(crate) roles: StorageView<'world, RoleId, Role>, /// Permission tokens of an account. @@ -262,10 +288,33 @@ impl World { } /// Creates a [`World`] with these [`Domain`]s and trusted [`PeerId`]s. - pub fn with(domains: D, accounts: A, trusted_peers_ids: PeersIds) -> Self + pub fn with( + domains: D, + accounts: A, + asset_definitions: Ad, + trusted_peers_ids: PeersIds, + ) -> Self where D: IntoIterator, A: IntoIterator, + Ad: IntoIterator, + { + Self::with_assets(domains, accounts, asset_definitions, [], trusted_peers_ids) + } + + /// Creates a [`World`] with these [`Domain`]s and trusted [`PeerId`]s. + pub fn with_assets( + domains: D, + accounts: A, + asset_definitions: Ad, + assets: As, + trusted_peers_ids: PeersIds, + ) -> Self + where + D: IntoIterator, + A: IntoIterator, + Ad: IntoIterator, + As: IntoIterator, { let domains = domains .into_iter() @@ -275,10 +324,17 @@ impl World { .into_iter() .map(|account| (account.id().clone(), account)) .collect(); + let asset_definitions = asset_definitions + .into_iter() + .map(|ad| (ad.id().clone(), ad)) + .collect(); + let assets = assets.into_iter().map(|ad| (ad.id().clone(), ad)).collect(); Self { trusted_peers_ids: Cell::new(trusted_peers_ids), domains, accounts, + asset_definitions, + assets, ..Self::new() } } @@ -290,6 +346,9 @@ impl World { trusted_peers_ids: self.trusted_peers_ids.block(), domains: self.domains.block(), accounts: self.accounts.block(), + asset_definitions: self.asset_definitions.block(), + asset_total_quantities: self.asset_total_quantities.block(), + assets: self.assets.block(), roles: self.roles.block(), account_permissions: self.account_permissions.block(), account_roles: self.account_roles.block(), @@ -307,6 +366,9 @@ impl World { trusted_peers_ids: self.trusted_peers_ids.block_and_revert(), domains: self.domains.block_and_revert(), accounts: self.accounts.block_and_revert(), + asset_definitions: self.asset_definitions.block_and_revert(), + asset_total_quantities: self.asset_total_quantities.block_and_revert(), + assets: self.assets.block_and_revert(), roles: self.roles.block_and_revert(), account_permissions: self.account_permissions.block_and_revert(), account_roles: self.account_roles.block_and_revert(), @@ -324,6 +386,9 @@ impl World { trusted_peers_ids: self.trusted_peers_ids.view(), domains: self.domains.view(), accounts: self.accounts.view(), + asset_definitions: self.asset_definitions.view(), + asset_total_quantities: self.asset_total_quantities.view(), + assets: self.assets.view(), roles: self.roles.view(), account_permissions: self.account_permissions.view(), account_roles: self.account_roles.view(), @@ -341,6 +406,9 @@ pub trait WorldReadOnly { fn trusted_peers_ids(&self) -> &PeersIds; fn domains(&self) -> &impl StorageReadOnly; fn accounts(&self) -> &impl StorageReadOnly; + fn asset_definitions(&self) -> &impl StorageReadOnly; + fn asset_total_quantities(&self) -> &impl StorageReadOnly; + fn assets(&self) -> &impl StorageReadOnly; fn roles(&self) -> &impl StorageReadOnly; fn account_permissions(&self) -> &impl StorageReadOnly; fn account_roles(&self) -> &impl StorageReadOnly; @@ -396,12 +464,52 @@ pub trait WorldReadOnly { .map(|(_, account)| account) } - /// Returns reference for domains map + /// Returns reference for accounts map #[inline] fn accounts_iter(&self) -> impl Iterator { self.accounts().iter().map(|(_, account)| account) } + /// Iterate asset definitions in domain + #[allow(clippy::type_complexity)] + fn asset_definitions_in_domain_iter<'slf>( + &'slf self, + id: &DomainId, + ) -> core::iter::Map< + RangeIter<'slf, AssetDefinitionId, AssetDefinition>, + fn((&'slf AssetDefinitionId, &'slf AssetDefinition)) -> &'slf AssetDefinition, + > { + self.asset_definitions() + .range::(AssetDefinitionByDomainBounds::new(id)) + .map(|(_, ad)| ad) + } + + /// Returns reference for asset definitions map + #[inline] + fn asset_definitions_iter(&self) -> impl Iterator { + self.asset_definitions().iter().map(|(_, ad)| ad) + } + + /// Iterate assets in account + #[allow(clippy::type_complexity)] + fn assets_in_account_iter<'slf>( + &'slf self, + id: &AccountId, + ) -> core::iter::Map< + RangeIter<'slf, AssetId, Asset>, + fn((&'slf AssetId, &'slf Asset)) -> &'slf Asset, + > { + self.assets() + .range::(AssetByAccountBounds::new(id)) + .map(|(_, a)| a) + } + + /// Returns reference for asset definitions map + #[inline] + fn assets_iter(&self) -> impl Iterator { + self.assets().iter().map(|(_, a)| a) + } + // Account-related methods /// Get `Account` and return reference to it. @@ -430,18 +538,6 @@ pub trait WorldReadOnly { Ok(f(account)) } - /// Get `Account`'s `Asset`s - /// - /// # Errors - /// Fails if there is no domain or account - fn account_assets( - &self, - id: &AccountId, - ) -> Result, QueryExecutionFail> - { - self.map_account(id, |account| account.assets.values()) - } - /// Get [`Account`]'s [`RoleId`]s // NOTE: have to use concreate type because don't want to capture lifetme of `id` #[allow(clippy::type_complexity)] @@ -516,16 +612,11 @@ pub trait WorldReadOnly { /// - The [`Account`] with which the [`Asset`] is associated doesn't exist. /// - The [`Domain`] with which the [`Account`] is associated doesn't exist. fn asset(&self, id: &AssetId) -> Result { - self.map_account( - &id.account, - |account| -> Result { - account - .assets - .get(&id.definition) - .ok_or_else(|| QueryExecutionFail::from(FindError::Asset(id.clone()))) - .cloned() - }, - )? + let _ = self.map_account(&id.account, |_| ())?; + self.assets() + .get(id) + .ok_or_else(|| QueryExecutionFail::from(FindError::Asset(id.clone()))) + .cloned() } // AssetDefinition-related methods @@ -535,8 +626,7 @@ pub trait WorldReadOnly { /// # Errors /// - Asset definition entry not found fn asset_definition(&self, asset_id: &AssetDefinitionId) -> Result { - self.domain(&asset_id.domain)? - .asset_definitions + self.asset_definitions() .get(asset_id) .ok_or_else(|| FindError::AssetDefinition(asset_id.clone())) .cloned() @@ -547,8 +637,7 @@ pub trait WorldReadOnly { /// # Errors /// - Asset definition not found fn asset_total_amount(&self, definition_id: &AssetDefinitionId) -> Result { - self.domain(&definition_id.domain)? - .asset_total_quantities + self.asset_total_quantities() .get(definition_id) .ok_or_else(|| FindError::AssetDefinition(definition_id.clone())) .copied() @@ -581,6 +670,15 @@ macro_rules! impl_world_ro { fn accounts(&self) -> &impl StorageReadOnly { &self.accounts } + fn asset_definitions(&self) -> &impl StorageReadOnly { + &self.asset_definitions + } + fn asset_total_quantities(&self) -> &impl StorageReadOnly { + &self.asset_total_quantities + } + fn assets(&self) -> &impl StorageReadOnly { + &self.assets + } fn roles(&self) -> &impl StorageReadOnly { &self.roles } @@ -615,6 +713,9 @@ impl<'world> WorldBlock<'world> { trusted_peers_ids: self.trusted_peers_ids.transaction(), domains: self.domains.transaction(), accounts: self.accounts.transaction(), + asset_definitions: self.asset_definitions.transaction(), + asset_total_quantities: self.asset_total_quantities.transaction(), + assets: self.assets.transaction(), roles: self.roles.transaction(), account_permissions: self.account_permissions.transaction(), account_roles: self.account_roles.transaction(), @@ -637,6 +738,9 @@ impl<'world> WorldBlock<'world> { self.account_roles.commit(); self.account_permissions.commit(); self.roles.commit(); + self.assets.commit(); + self.asset_total_quantities.commit(); + self.asset_definitions.commit(); self.accounts.commit(); self.domains.commit(); self.trusted_peers_ids.commit(); @@ -653,6 +757,9 @@ impl WorldTransaction<'_, '_> { self.account_roles.apply(); self.account_permissions.apply(); self.roles.apply(); + self.assets.apply(); + self.asset_total_quantities.apply(); + self.asset_definitions.apply(); self.accounts.apply(); self.domains.apply(); self.trusted_peers_ids.apply(); @@ -729,12 +836,10 @@ impl WorldTransaction<'_, '_> { /// # Errors /// If domain, account or asset not found pub fn asset_mut(&mut self, id: &AssetId) -> Result<&mut Asset, FindError> { - self.account_mut(&id.account).and_then(move |account| { - account - .assets - .get_mut(&id.definition) - .ok_or_else(|| FindError::Asset(id.clone())) - }) + let _ = self.account(&id.account)?; + self.assets + .get_mut(id) + .ok_or_else(|| FindError::Asset(id.clone())) } /// Get asset or inserts new with `default_asset_value`. @@ -749,36 +854,24 @@ impl WorldTransaction<'_, '_> { ) -> Result<&mut Asset, Error> { // Check that asset definition exists { - let asset_definition_id = &asset_id.definition; - let asset_definition_domain_id = &asset_id.definition.domain; - let asset_definition_domain = self - .domains - .get(asset_definition_domain_id) - .ok_or(FindError::Domain(asset_definition_domain_id.clone()))?; - asset_definition_domain - .asset_definitions - .get(asset_definition_id) - .ok_or(FindError::AssetDefinition(asset_definition_id.clone()))?; + let _ = self.domain(&asset_id.definition.domain)?; + let _ = self.asset_definition(&asset_id.definition)?; } - let account_id = &asset_id.account; - let account = self - .accounts - .get_mut(account_id) - .ok_or(FindError::Account(account_id.clone()))?; - - Ok(account + let _ = self.account(&asset_id.account)?; + if self.assets.get(&asset_id).is_none() { + let asset = Asset::new(asset_id.clone(), default_asset_value.into()); + Self::emit_events_impl( + &mut self.triggers, + &mut self.events_buffer, + Some(AssetEvent::Created(asset.clone())), + ); + self.assets.insert(asset_id.clone(), asset); + } + Ok(self .assets - .entry(asset_id.definition.clone()) - .or_insert_with(|| { - let asset = Asset::new(asset_id, default_asset_value.into()); - Self::emit_events_impl( - &mut self.triggers, - &mut self.events_buffer, - Some(AccountEvent::Asset(AssetEvent::Created(asset.clone()))), - ); - asset - })) + .get_mut(&asset_id) + .expect("Just inserted, cannot fail.")) } /// Get mutable reference to [`AssetDefinition`] @@ -789,12 +882,9 @@ impl WorldTransaction<'_, '_> { &mut self, id: &AssetDefinitionId, ) -> Result<&mut AssetDefinition, FindError> { - self.domain_mut(&id.domain).and_then(|domain| { - domain - .asset_definitions - .get_mut(id) - .ok_or_else(|| FindError::AssetDefinition(id.clone())) - }) + self.asset_definitions + .get_mut(id) + .ok_or_else(|| FindError::AssetDefinition(id.clone())) } /// Increase [`Asset`] total amount by given value @@ -807,9 +897,8 @@ impl WorldTransaction<'_, '_> { definition_id: &AssetDefinitionId, increment: Numeric, ) -> Result<(), Error> { - let domain = self.domain_mut(&definition_id.domain)?; let asset_total_amount: &mut Numeric = - domain.asset_total_quantities.get_mut(definition_id).expect( + self.asset_total_quantities.get_mut(definition_id).expect( "INTERNAL BUG: Asset total amount not found. \ Insert initial total amount on `Register`", ); @@ -840,9 +929,8 @@ impl WorldTransaction<'_, '_> { definition_id: &AssetDefinitionId, decrement: Numeric, ) -> Result<(), Error> { - let domain = self.domain_mut(&definition_id.domain)?; let asset_total_amount: &mut Numeric = - domain.asset_total_quantities.get_mut(definition_id).expect( + self.asset_total_quantities.get_mut(definition_id).expect( "INTERNAL BUG: Asset total amount not found. \ Insert initial total amount on `Register`", ); @@ -1531,6 +1619,116 @@ mod range_bounds { key: AccountIdDomainCompare<'_>, trait: AsAccountIdDomainCompare } + + /// `DomainId` wrapper for fetching asset definitions beloning to a domain from the global store + #[derive(PartialEq, Eq, Ord, PartialOrd, Copy, Clone)] + pub struct AssetDefinitionIdDomainCompare<'a> { + domain_id: &'a DomainId, + name: MinMaxExt<&'a Name>, + } + + /// Bounds for range quired over asset definitions by domain + pub struct AssetDefinitionByDomainBounds<'a> { + start: AssetDefinitionIdDomainCompare<'a>, + end: AssetDefinitionIdDomainCompare<'a>, + } + + impl<'a> AssetDefinitionByDomainBounds<'a> { + /// Create range bounds for range quires over asset definitions by domain + pub fn new(domain_id: &'a DomainId) -> Self { + Self { + start: AssetDefinitionIdDomainCompare { + domain_id, + name: MinMaxExt::Min, + }, + end: AssetDefinitionIdDomainCompare { + domain_id, + name: MinMaxExt::Max, + }, + } + } + } + + impl<'a> RangeBounds + for AssetDefinitionByDomainBounds<'a> + { + fn start_bound(&self) -> Bound<&(dyn AsAssetDefinitionIdDomainCompare + 'a)> { + Bound::Excluded(&self.start) + } + + fn end_bound(&self) -> Bound<&(dyn AsAssetDefinitionIdDomainCompare + 'a)> { + Bound::Excluded(&self.end) + } + } + + impl AsAssetDefinitionIdDomainCompare for AssetDefinitionId { + fn as_key(&self) -> AssetDefinitionIdDomainCompare<'_> { + AssetDefinitionIdDomainCompare { + domain_id: &self.domain, + name: (&self.name).into(), + } + } + } + + impl_as_dyn_key! { + target: AssetDefinitionId, + key: AssetDefinitionIdDomainCompare<'_>, + trait: AsAssetDefinitionIdDomainCompare + } + + /// `AccountId` wrapper for fetching assets beloning to an account from the global store + #[derive(PartialEq, Eq, Ord, PartialOrd, Copy, Clone)] + pub struct AssetIdAccountCompare<'a> { + account_id: &'a AccountId, + definition: MinMaxExt<&'a AssetDefinitionId>, + } + + /// Bounds for range quired over assets by account + pub struct AssetByAccountBounds<'a> { + start: AssetIdAccountCompare<'a>, + end: AssetIdAccountCompare<'a>, + } + + impl<'a> AssetByAccountBounds<'a> { + /// Create range bounds for range quires over assets by account + pub fn new(account_id: &'a AccountId) -> Self { + Self { + start: AssetIdAccountCompare { + account_id, + definition: MinMaxExt::Min, + }, + end: AssetIdAccountCompare { + account_id, + definition: MinMaxExt::Max, + }, + } + } + } + + impl<'a> RangeBounds for AssetByAccountBounds<'a> { + fn start_bound(&self) -> Bound<&(dyn AsAssetIdAccountCompare + 'a)> { + Bound::Excluded(&self.start) + } + + fn end_bound(&self) -> Bound<&(dyn AsAssetIdAccountCompare + 'a)> { + Bound::Excluded(&self.end) + } + } + + impl AsAssetIdAccountCompare for AssetId { + fn as_key(&self) -> AssetIdAccountCompare<'_> { + AssetIdAccountCompare { + account_id: &self.account, + definition: (&self.definition).into(), + } + } + } + + impl_as_dyn_key! { + target: AssetId, + key: AssetIdAccountCompare<'_>, + trait: AsAssetIdAccountCompare + } } pub(crate) mod deserialize { @@ -1628,6 +1826,9 @@ pub(crate) mod deserialize { let mut trusted_peers_ids = None; let mut domains = None; let mut accounts = None; + let mut asset_definitions = None; + let mut asset_total_quantities = None; + let mut assets = None; let mut roles = None; let mut account_permissions = None; let mut account_roles = None; @@ -1649,6 +1850,15 @@ pub(crate) mod deserialize { "accounts" => { accounts = Some(map.next_value()?); } + "asset_definitions" => { + asset_definitions = Some(map.next_value()?); + } + "asset_total_quantities" => { + asset_total_quantities = Some(map.next_value()?); + } + "assets" => { + assets = Some(map.next_value()?); + } "roles" => { roles = Some(map.next_value()?); } @@ -1684,6 +1894,12 @@ pub(crate) mod deserialize { .ok_or_else(|| serde::de::Error::missing_field("domains"))?, accounts: accounts .ok_or_else(|| serde::de::Error::missing_field("accounts"))?, + asset_definitions: asset_definitions + .ok_or_else(|| serde::de::Error::missing_field("asset_definitions"))?, + asset_total_quantities: asset_total_quantities.ok_or_else(|| { + serde::de::Error::missing_field("asset_total_quantities") + })?, + assets: assets.ok_or_else(|| serde::de::Error::missing_field("assets"))?, roles: roles.ok_or_else(|| serde::de::Error::missing_field("roles"))?, account_permissions: account_permissions.ok_or_else(|| { serde::de::Error::missing_field("account_permissions") @@ -1929,4 +2145,40 @@ mod tests { assert_eq!(&account.domain, &domain_id); } } + + #[test] + fn asset_account_range() { + let domain_id: DomainId = "wonderland".parse().unwrap(); + + let account_id = gen_account_in("wonderland").0; + + let accounts = [ + account_id.clone(), + account_id.clone(), + gen_account_in("a").0, + gen_account_in("b").0, + gen_account_in("z").0, + gen_account_in("z").0, + ]; + let asset_definitions = [ + AssetDefinitionId::new(domain_id.clone(), "a".parse().unwrap()), + AssetDefinitionId::new(domain_id.clone(), "f".parse().unwrap()), + AssetDefinitionId::new(domain_id.clone(), "b".parse().unwrap()), + AssetDefinitionId::new(domain_id.clone(), "c".parse().unwrap()), + AssetDefinitionId::new(domain_id.clone(), "d".parse().unwrap()), + AssetDefinitionId::new(domain_id.clone(), "e".parse().unwrap()), + ]; + + let assets = accounts + .into_iter() + .zip(asset_definitions) + .map(|(account, asset_definiton)| AssetId::new(asset_definiton, account)) + .map(|asset| (asset, ())); + + let map = Storage::from_iter(assets); + + let view = map.view(); + let range = view.range(AssetByAccountBounds::new(&account_id)); + assert_eq!(range.count(), 2); + } } diff --git a/core/src/sumeragi/main_loop.rs b/core/src/sumeragi/main_loop.rs index f8c2d8dd17b..af21b124381 100644 --- a/core/src/sumeragi/main_loop.rs +++ b/core/src/sumeragi/main_loop.rs @@ -1365,7 +1365,7 @@ mod tests { let account = Account::new(alice_id.clone()).build(&alice_id); let domain_id = "wonderland".parse().expect("Valid"); let domain = Domain::new(domain_id).build(&alice_id); - let world = World::with([domain], [account], topology.iter().cloned().collect()); + let world = World::with([domain], [account], [], topology.iter().cloned().collect()); let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); let state = State::new(world, Arc::clone(&kura), query_handle); diff --git a/data_model/src/account.rs b/data_model/src/account.rs index c8daf5c8cb3..0717190102d 100644 --- a/data_model/src/account.rs +++ b/data_model/src/account.rs @@ -12,10 +12,7 @@ use serde_with::{DeserializeFromStr, SerializeDisplay}; pub use self::model::*; use crate::{ - asset::{Asset, AssetDefinitionId, AssetsMap}, - domain::prelude::*, - metadata::Metadata, - HasMetadata, ParseError, PublicKey, Registered, + domain::prelude::*, metadata::Metadata, HasMetadata, ParseError, PublicKey, Registered, }; #[model] @@ -75,8 +72,6 @@ mod model { pub struct Account { /// Identification of the [`Account`]. pub id: AccountId, - /// Assets in this [`Account`]. - pub assets: AssetsMap, /// Metadata of this account as a key-value store. pub metadata: Metadata, } @@ -118,34 +113,6 @@ impl Account { pub fn signatory(&self) -> &PublicKey { &self.id.signatory } - - /// Return a reference to the [`Asset`] corresponding to the asset id. - #[inline] - pub fn asset(&self, asset_id: &AssetDefinitionId) -> Option<&Asset> { - self.assets.get(asset_id) - } - - /// Get an iterator over [`Asset`]s of the `Account` - #[inline] - pub fn assets(&self) -> impl ExactSizeIterator { - self.assets.values() - } -} - -#[cfg(feature = "transparent_api")] -impl Account { - /// Add [`Asset`] into the [`Account`] returning previous asset stored under the same id - #[inline] - pub fn add_asset(&mut self, asset: Asset) -> Option { - assert_eq!(self.id, asset.id.account); - self.assets.insert(asset.id.definition.clone(), asset) - } - - /// Remove asset from the [`Account`] and return it - #[inline] - pub fn remove_asset(&mut self, asset_id: &AssetDefinitionId) -> Option { - self.assets.remove(asset_id) - } } impl NewAccount { @@ -171,7 +138,6 @@ impl NewAccount { pub fn into_account(self) -> Account { Account { id: self.id, - assets: AssetsMap::default(), metadata: self.metadata, } } diff --git a/data_model/src/asset.rs b/data_model/src/asset.rs index 7e4e1c43f9b..dfdaf640875 100644 --- a/data_model/src/asset.rs +++ b/data_model/src/asset.rs @@ -20,13 +20,6 @@ use crate::{ ParseError, Registered, }; -/// API to work with collections of [`Id`] : [`Asset`] mappings. -pub type AssetsMap = btree_map::BTreeMap; - -/// [`AssetDefinitionsMap`] provides an API to work with collection of key([`AssetDefinitionId`])-value([`AssetDefinition`]) -/// pairs. -pub type AssetDefinitionsMap = btree_map::BTreeMap; - /// [`AssetTotalQuantityMap`] provides an API to work with collection of key([`AssetDefinitionId`])-value([`AssetValue`]) /// pairs. pub type AssetTotalQuantityMap = btree_map::BTreeMap; @@ -83,7 +76,6 @@ mod model { PartialOrd, Ord, Hash, - Constructor, Getters, Decode, Encode, @@ -94,10 +86,10 @@ mod model { #[getset(get = "pub")] #[ffi_type] pub struct AssetId { - /// Entity Identification. - pub definition: AssetDefinitionId, /// Account Identification. pub account: AccountId, + /// Entity Identification. + pub definition: AssetDefinitionId, } /// Asset definition defines the type of that asset. @@ -302,6 +294,16 @@ impl AssetDefinition { } } +impl AssetId { + /// Create a new AssetId + pub fn new(definition: AssetDefinitionId, account: AccountId) -> Self { + Self { + account, + definition, + } + } +} + impl Asset { /// Constructor pub fn new(id: AssetId, value: impl Into) -> ::With { diff --git a/data_model/src/domain.rs b/data_model/src/domain.rs index fba99212f45..8789ea47a34 100644 --- a/data_model/src/domain.rs +++ b/data_model/src/domain.rs @@ -5,20 +5,13 @@ use alloc::{format, string::String, vec::Vec}; use derive_more::{Constructor, Display, FromStr}; use iroha_data_model_derive::{model, IdEqOrdHash}; -use iroha_primitives::numeric::Numeric; use iroha_schema::IntoSchema; use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; use serde_with::{DeserializeFromStr, SerializeDisplay}; pub use self::model::*; -use crate::{ - asset::{AssetDefinition, AssetDefinitionsMap, AssetTotalQuantityMap}, - ipfs::IpfsPath, - metadata::Metadata, - prelude::*, - HasMetadata, Name, Registered, -}; +use crate::{ipfs::IpfsPath, metadata::Metadata, prelude::*, HasMetadata, Name, Registered}; #[model] mod model { @@ -73,10 +66,6 @@ mod model { pub struct Domain { /// Identification of this [`Domain`]. pub id: DomainId, - /// [`Asset`](AssetDefinition)s defined of the `Domain`. - pub asset_definitions: AssetDefinitionsMap, - /// Total amount of [`Asset`]. - pub asset_total_quantities: AssetTotalQuantityMap, /// IPFS link to the [`Domain`] logo. #[getset(get = "pub")] pub logo: Option, @@ -155,76 +144,6 @@ impl Domain { } } -impl Domain { - /// Return a reference to the asset definition corresponding to the asset definition id - #[inline] - pub fn asset_definition( - &self, - asset_definition_id: &AssetDefinitionId, - ) -> Option<&AssetDefinition> { - self.asset_definitions.get(asset_definition_id) - } - - /// Return a reference to the asset definition corresponding to the asset definition id - #[inline] - pub fn asset_total_quantity( - &self, - asset_definition_id: &AssetDefinitionId, - ) -> Option<&Numeric> { - self.asset_total_quantities.get(asset_definition_id) - } - - /// Get an iterator over asset definitions of the `Domain` - #[inline] - pub fn asset_definitions(&self) -> impl ExactSizeIterator { - self.asset_definitions.values() - } -} - -#[cfg(feature = "transparent_api")] -impl Domain { - /// Add asset definition into the [`Domain`] returning previous - /// asset definition stored under the same id - #[inline] - pub fn add_asset_definition( - &mut self, - asset_definition: AssetDefinition, - ) -> Option { - self.asset_definitions - .insert(asset_definition.id().clone(), asset_definition) - } - - /// Remove asset definition from the [`Domain`] and return it - #[inline] - pub fn remove_asset_definition( - &mut self, - asset_definition_id: &AssetDefinitionId, - ) -> Option { - self.asset_definitions.remove(asset_definition_id) - } - - /// Add asset total amount into the [`Domain`] returning previous - /// asset amount stored under the same id - #[inline] - pub fn add_asset_total_quantity( - &mut self, - asset_definition_id: AssetDefinitionId, - initial_amount: Numeric, - ) -> Option { - self.asset_total_quantities - .insert(asset_definition_id, initial_amount) - } - - /// Remove asset total amount from the [`Domain`] and return it - #[inline] - pub fn remove_asset_total_quantity( - &mut self, - asset_definition_id: &AssetDefinitionId, - ) -> Option { - self.asset_total_quantities.remove(asset_definition_id) - } -} - /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { pub use super::{Domain, DomainId}; diff --git a/data_model/src/events/data/filters.rs b/data_model/src/events/data/filters.rs index 0bda7058181..20dbf6e0d3d 100644 --- a/data_model/src/events/data/filters.rs +++ b/data_model/src/events/data/filters.rs @@ -724,7 +724,6 @@ mod tests { use iroha_crypto::KeyPair; use super::*; - use crate::asset::{AssetDefinitionsMap, AssetTotalQuantityMap}; #[test] #[cfg(feature = "transparent_api")] @@ -736,8 +735,6 @@ mod tests { let domain = Domain { id: domain_id.clone(), - asset_definitions: AssetDefinitionsMap::default(), - asset_total_quantities: AssetTotalQuantityMap::default(), logo: None, metadata: Metadata::default(), owned_by: domain_owner_id, diff --git a/docs/source/references/schema.json b/docs/source/references/schema.json index ec3064d9867..65ed5f1a562 100644 --- a/docs/source/references/schema.json +++ b/docs/source/references/schema.json @@ -5,10 +5,6 @@ "name": "id", "type": "AccountId" }, - { - "name": "assets", - "type": "SortedMap" - }, { "name": "metadata", "type": "Metadata" @@ -470,13 +466,13 @@ }, "AssetId": { "Struct": [ - { - "name": "definition", - "type": "AssetDefinitionId" - }, { "name": "account", "type": "AccountId" + }, + { + "name": "definition", + "type": "AssetDefinitionId" } ] }, @@ -1166,14 +1162,6 @@ "name": "id", "type": "DomainId" }, - { - "name": "asset_definitions", - "type": "SortedMap" - }, - { - "name": "asset_total_quantities", - "type": "SortedMap" - }, { "name": "logo", "type": "Option" @@ -3854,24 +3842,6 @@ } ] }, - "SortedMap": { - "Map": { - "key": "AssetDefinitionId", - "value": "Asset" - } - }, - "SortedMap": { - "Map": { - "key": "AssetDefinitionId", - "value": "AssetDefinition" - } - }, - "SortedMap": { - "Map": { - "key": "AssetDefinitionId", - "value": "Numeric" - } - }, "SortedMap": { "Map": { "key": "CustomParameterId", diff --git a/tools/parity_scale_cli/samples/trigger.bin b/tools/parity_scale_cli/samples/trigger.bin index d46095a94fd..3016bb36d2d 100644 Binary files a/tools/parity_scale_cli/samples/trigger.bin and b/tools/parity_scale_cli/samples/trigger.bin differ