hyperledger-iroha / iroha

Iroha - A simple, enterprise-grade decentralized ledger
https://wiki.hyperledger.org/display/iroha
Apache License 2.0
438 stars 280 forks source link

Redundant identifiers in storage values #5034

Open nxsaken opened 1 month ago

nxsaken commented 1 month ago

We can save space if we remove identifiers from storage values. For example, Storage<AccountId, Account> is really Storage<AccountId, (AccountId, Metadata)>. It also prevents accidentally leaving the world in an inconsistent state by mutating the identifier in the value separately from the key.

This could look like the following:

struct AssetId(...);
enum AssetValue { ... };

struct Asset {
  id: AssetId,
  value: AssetValue,
}

// could be a generic struct representing an `mv` entry
struct AssetEntry<'world> {
  id: &'world AssetId,
  value: &'world AssetValue,
}

struct AssetEntryMut<'world> {
  id: &'world AssetId,
  value: &'world mut AssetValue,
}

struct World {
  assets: Storage<AssetId, AssetValue>,
  ...
}

impl World {
  fn iter_assets(&self) -> impl Iterator<Item = AssetEntry> {
    self.assets().iter().map(|(id, value)| AssetEntry { id, value })
  }

  fn asset_mut(&mut self, id: &AssetId) -> Result<&mut AssetValue, FindError> {
    ...
  }
}

I encountered a problem with queries while trying this: predicates don't seem to support inputs with lifetimes.

Would this be worth pursuing?