cosmos / cosmos-sdk

:chains: A Framework for Building High Value Public Blockchains :sparkles:
https://cosmos.network/
Apache License 2.0
6.26k stars 3.62k forks source link

feat(collections): implement LookupMap and TreeMap #18732

Open testinginprod opened 10 months ago

testinginprod commented 10 months ago

Context

In order to make the SDK provable, the assumptions we need to make around storage or the underlying commitment structure need to be smaller.

Currently all the modules assume that the underlying KV can:

But it should not always be a given that the underlying storage can iterate. And it should not be a given that when iteration happens the underlying commitment structure can prove the iteration range (RangeProofs).

Also not all modules need iterations by default. Iteration is always needed for genesis, but it is not always required for the module to execute its own state transitions.

In order to reduce the assumption around state storage to be:

And in order to reduce the assumptions around commitment structure to be:

We propose to introduce two new collections types:

LookupMap

LookupMap is like a Map[K, V] but is not iterable.

In order to implement this, it should be sufficient to take (literal copy paste) the collections.Map code and remove the following methods:

TreeMap

TreeMap is like a LookupMap  but provides ordered iteration. It builds an iterable (ordered) tree on top of the KV.

We can find an example here: https://docs.rs/near-sdk/latest/src/near_sdk/collections/tree_map.rs.html#42

alexanderbez commented 10 months ago

SGTM!

kocubinski commented 10 months ago

I think this abstraction makes sense to support other commitment types. For the current status quo in the SDK (IAVL) TreeMap could just be a pass through.

robert-zaremba commented 10 months ago

I'm very familiar with the Near data model, and honestly, I think that removing "native" iterations is a premature abstraction. It's a clear overhead for map structure which requires prefix scan or ordered scan. The TreeMap is done by implementing AVL structure of the KV store. So, here it would either be AVL over IAVL (sic!), or AVL over KV when we have SS (which usually is also a sort of a tree).

robert-zaremba commented 10 months ago

I think the proposal can be implemented as "optional", but we should still keep the current model, so module developers an use the existing assumptions like efficient prefix scan, which is often used!

tac0turtle commented 10 months ago

I think the proposal can be implemented as "optional", but we should still keep the current model, so module developers an use the existing assumptions like efficient prefix scan, which is often used!

We won't be removing the current design as state migrations would be horrendous. If chains or modules want to be more efficient in proving they will need to do something like this.