Skip to content

Rethink Extern #584

Closed
Closed
@ethanfrey

Description

@ethanfrey

Problem

In order to pass in all the external deps, we currently use:

pub struct Extern<S: Storage, A: Api, Q: Querier> {
    pub storage: S,
    pub api: A,
    pub querier: Q,
}

and pass in either &mut Extern (handle, init, migrate) or &Extern (query).

This is great for tests and for linking to relatively stateless handlers. Now, I am working to build a integration test framework for contracts to redeploy messages and router querier to the real contracts and their state - held by the same object that is running the query itself.

The current definition means I need to pass in self, when all that is really needed is &self. I start defining impl Querier for &Router (rather than Router) and got into all kinds of lifetime issues. I also could not accept &Q, as I need Q for building Extern.

Proposal

What we really need inside the contracts is:

pub struct ExternMut<S: Storage, A: Api, Q: Querier> {
    pub storage: &mut S,
    pub api: &A,
    pub querier: &Q,
}

pub struct ExternRef<S: Storage, A: Api, Q: Querier> {
    pub storage: &S,
    pub api: &A,
    pub querier: &Q,
}

and can use handle(deps: ExternMut<S, A, Q>, ..) and query(deps: ExternRef<S, A, Q>, ...)

Impact

We could easily implement Extern::as_ref() and Extern::as_mut() to produce these from one owned Extern. This would be used almost identically inside the contract code (probably less typing - deps.storage rather than &mut deps.storage), but would make a bit more typing in the test code (mock_dependencies must return Extern for ownership, then all calls would be like: handle(deps.as_mut(), ...)

I do believe this would not change the wasm<->Rust API, just the unit tests, so pre-compiled 0.11 wasm binaries would be drop-in compatible with a new network with this change. You could just update the code in the next version of each contract, without requiring an upgrade of every contract to use the new network.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions