Skip to content

Simple Mapping Storage Primitive #945

@HCastano

Description

@HCastano

Motivation

At the moment, ink! data structures, such as the ink_storage::LazyHashMap, are quite
complicated. This is because they were designed in a very "polite" way. That's to say,
they did a lot of internal bookkeeping to ensure that they cleaned up after themselves,
and that they were only going to the contract storage database when it was absolutely
neccessary.

While this was great from a user's point of view, this approach to data structure in
ink! has lead to contract sizes being larger than they probably need to be.

As such, we want to experiment with some simpler data structures, such as a Solidity-like
mapping.

ink_storage::Mapping

The new ink_storage::Mapping would be a paper thin type-safe wrapper around some of the
ink_storage and ink_env storage primitives.

The Mapping type would look as follows:

struct Mapping<K, V>(PhantomData<K>, PhantomData<V>);

Note that we may also need some sort of Key field to differentiate between different
instances of Mapping and avoid collisions. This would be similar to what LazyHashMap
does.

The API of the Mapping would look (roughly) like this:

impl<K, V: Default> Mapping<K, V> {
    ...

    /// Write value to `key`.
    fn push(&mut self, key: K, value: V) {
        todo!()
    }

    /// Get the value at `key`.
    ///
    /// If there is no value at the `key` it will return the default value.
    fn get(&self, key: K) -> V {
        todo!()
    }

    ...
}

It would also need to implement the SpreadLayout and PackedLayout traits. This is
what would actually be doing the heavy lifting as far as talking to the contract storage
goes.

Another thing that will have to get done is adding some new low level push/pull
functions which allow the return values to be empty. At the moment these functions assume
that if you're querying for a key, that it already exists.

This would not be the case with the new Mapping, since you can query any key and if it
doesn't exist you'd get the Default value back.

ERC-20 Benchmarking

After implementing the new Mapping type we want to implement a new ERC-20 example
contract with it. The thing to look for here is how much better (or worse) the contract
sizes are compared to our current ERC-20 example.

Metadata

Metadata

Assignees

Labels

A-ink_storage[ink_storage] Work ItemB-enhancementNew feature or requestB-researchResearch task that has open questions that need to be resolved.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions