From 2e65e00f31fc6dee8df6f957f89a8bb000d781ca Mon Sep 17 00:00:00 2001 From: Mirko von Leipzig Date: Wed, 17 Jul 2024 12:19:20 +0200 Subject: [PATCH] feat: prefer BTreeMap to HashMap The latter is not nostd compliant. --- objects/src/accounts/delta/vault.rs | 4 ++-- objects/src/assets/fungible.rs | 2 +- objects/src/assets/mod.rs | 2 +- objects/src/assets/nonfungible.rs | 22 ++++++++++++++++++---- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/objects/src/accounts/delta/vault.rs b/objects/src/accounts/delta/vault.rs index d1be396c7..de66a78ec 100644 --- a/objects/src/accounts/delta/vault.rs +++ b/objects/src/accounts/delta/vault.rs @@ -1,5 +1,5 @@ use alloc::{string::ToString, vec::Vec}; -use std::collections::HashMap; +use std::collections::BTreeMap; use super::{ AccountDeltaError, Asset, ByteReader, ByteWriter, Deserializable, DeserializationError, @@ -52,7 +52,7 @@ impl AccountVaultDelta { .chain(self.removed_assets.into_iter().map(|asset| (asset, true))) .chain(other.added_assets.into_iter().map(|asset| (asset, false))) .chain(other.removed_assets.into_iter().map(|asset| (asset, false))) - .collect::>(); + .collect::>(); let added = assets.iter().filter_map(|(asset, was_added)| was_added.then_some(*asset)); let removed = assets.iter().filter_map(|(asset, was_added)| (!was_added).then_some(*asset)); diff --git a/objects/src/assets/fungible.rs b/objects/src/assets/fungible.rs index 9ed66695e..327d53d05 100644 --- a/objects/src/assets/fungible.rs +++ b/objects/src/assets/fungible.rs @@ -12,7 +12,7 @@ use super::{ /// /// A fungible asset consists of a faucet ID of the faucet which issued the asset as well as the /// asset amount. Asset amount is guaranteed to be 2^63 - 1 or smaller. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct FungibleAsset { faucet_id: AccountId, diff --git a/objects/src/assets/mod.rs b/objects/src/assets/mod.rs index 808cff466..6dbb7aff5 100644 --- a/objects/src/assets/mod.rs +++ b/objects/src/assets/mod.rs @@ -63,7 +63,7 @@ pub use vault::AssetVault; /// as the faucet_id is included in the description of the non-fungible asset and this is guaranteed /// to be different as per the faucet creation logic. Collision resistance for non-fungible assets /// issued by the same faucet is ~2^95. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub enum Asset { Fungible(FungibleAsset), diff --git a/objects/src/assets/nonfungible.rs b/objects/src/assets/nonfungible.rs index d55ca2c21..336c4fe12 100644 --- a/objects/src/assets/nonfungible.rs +++ b/objects/src/assets/nonfungible.rs @@ -26,11 +26,25 @@ const FAUCET_ID_POS: usize = 1; #[cfg_attr(feature = "serde", serde(transparent))] pub struct NonFungibleAsset(Word); -impl std::hash::Hash for NonFungibleAsset { - fn hash(&self, state: &mut H) { - for felt in self.0 { - felt.inner().hash(state) +impl PartialOrd for NonFungibleAsset { + fn partial_cmp(&self, other: &Self) -> Option { + /// This wrapper allows us to use iterators builtin partial ord implementation. + /// This is much safer than attempting to do this correctly. + #[derive(PartialEq, Eq)] + struct Helper<'a>(&'a Felt); + impl PartialOrd for Helper<'_> { + fn partial_cmp(&self, other: &Self) -> Option { + self.0.inner().partial_cmp(&other.0.inner()) + } } + + self.0.iter().map(Helper).partial_cmp(other.0.iter().map(Helper)) + } +} + +impl Ord for NonFungibleAsset { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.partial_cmp(other).expect("NonFungibleAsset should always be Orderable") } }