2

For my dapp I need storage which can reference a mutable amount of events, all of which have their own orderbook. Expanded, it looks something like this:

CoreStorage {
    coin_storage: CoinStore, //not the issue
    event_storage: {
        event_type_1: Mapping<EventId, EventType1>,
        event_type_2: Mapping<EventId, EventType2>,
    }

EventType1 {
    event_info: EventInfo,
    event_orderbook: EventOrderBook //where the issue lies
}

EventOrderbook {
    orders_0: Mapping<AccountId, Order>, //this is impossible from what I can tell
    orders_1: Mapping<AccountId, Order> 
}

Nested Mapping structures are not supported by design. Likely the final data structure will not be a Mapping type, something much more performant for sorted lookups, but regardless it will not be able to adhere to the PackedLayout trait (this is just what I assume with my current knowledge).

My only thought I have to make this work is to have a separate smart contract for every EventOrderbook that communicates back to the main smart contract, so the storage structure will be replaced with something like:

use event_contract::EventContract

EventType1 {
    event_info: EventInfo,
    event_contract: EventContract
}

and in another crate I would have a contract that is compiled as a dependency that I can instantiate when I instantiate this main contract.

Is this the correct approach? Or is there some more efficient way I should be doing this?

Thank you! Any help or documentation would be appreciated.

2 Answers 2

2

As Mapping inside Mapping is not supported explanation here. The best way is to use a tuple:

If you have this structure:

Map<A, Map<B, C>>

You can structure it like this:

Map<(A, B), C>

In your example it can be:

EventType1 {
    event_info: EventInfo,
}

CoreStorage {
    coin_storage: CoinStore, //not the issue
    event_storage: {
        event_type_1: Mapping<EventId, EventType1>,
        event_type_2: Mapping<EventId, EventType2>,
        order_0: Mapping<(EventId, AccountId), Order>
        order_1: Mapping<(EventId, AccountId), Order>
    }

And then you can access Orders with EventId & AccountId.

2

In addition to the other answer, there is a possibility to use a different data-structure for nested-mappings. An easy to implement one is BTreeMap. It is worth noting that BTreeMap is not as efficient as Mapping. See this answer for details.

Here is an example implementation based on your code:

use ink_prelude::collections::BTreeMap;

CoreStorage {
    coin_storage: CoinStore,
    event_storage: {
        event_type_1: Mapping<EventId, EventType1>,
        event_type_2: Mapping<EventId, EventType2>,
    }

EventType1 {
    event_info: EventInfo,
    event_orderbook: EventOrderBook
}

EventOrderbook {
    orders_0: BTreeMap<AccountId, Order>,
    orders_1: BTreeMap<AccountId, Order> 
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.