Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Migrate webassembly to snap module #103

Open
3 tasks
tmpfs opened this issue Mar 29, 2023 · 1 comment
Open
3 tasks

Migrate webassembly to snap module #103

tmpfs opened this issue Mar 29, 2023 · 1 comment
Assignees

Comments

@tmpfs
Copy link
Collaborator

tmpfs commented Mar 29, 2023

Moving the webassembly execution to the snap code will enhance the security of the key shares as they will no longer be exposed to the dapp code and also enable threshold signatures to be accessible from multiple dapps.

This is now feasible after the recent changes that removed the dependency upon wasm-bindgen-rayon thanks to this rayon PR which in turn removes the need to use SharedArrayBuffer (which is not available in the snaps execution environment) as the backing memory for the webassembly execution.

There are several important considerations, which are summarized here:

  • A bridge module will need to proxy between the networking logic (executing in the dapp context) and the webassembly execution (snap context)
  • Build support for embedded buffer (wasm-pack)
  • Bundled snap will trigger the GPLv3 license
  1. Bridge module

The snap code cannot access the network and we need to transfer messages between parties using WebSocket so we would need a module that bridges the websocket transport with calls into the snap API which will proxy the webassembly execution. Developers building dapps that need to use the threshold signatures API would need to compile against this bridge module to communicate with the snap.

  1. Embedded buffer

The webassembly snaps example requires that the webassembly module is embedded as a buffer and instantiated directly. But we are working with rich data types not just numbers so we use wasm-bindgen and compile it with wasm-pack to get Javascript bindings to the webassembly module. The wasm-pack tool will generate code that loads the webassembly from a URL, here is an example of the generated init function:

async function init(input) {
    if (typeof input === 'undefined') {
        input = new URL('mpc_ecdsa_wasm_bg.wasm', import.meta.url);
    }
    const imports = getImports();

    if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
        input = fetch(input);
    }

    initMemory(imports);

    const { instance, module } = await load(await input, imports);

    return finalizeInit(instance, module);
}

We would need to rewrite this init function to embed the webassembly buffer. Ideally, we can upstream this work to wasm-pack so that other snaps developers can use wasm-bindgen with snaps.

  1. Bundled snap licensing

If the TSS snap is bundled with MM (to workaround browser extension restrictions on executing non-bundled code) then it is quite possible that it would trigger the GPLv3 license for the browser extension. We need clarification on whether it is going to be possible to load non-bundled snaps.

Other considerations

There are many unknowns with getting this to work and in particular whether the snaps execution lifecycle could interfere with the MPC sessions. Snaps execute with a lambda style execution and we don't have any clear idea of a snap lifecycle but this use case requires potentially long-running communication between the dapp and the snap to perform DKG and signing. Is it possible the snap could be stopped whilst a session is running?

Performance will likely be impacted as we will now have additional hops to call out to the browser extension which proxies to the snaps execution environment, executes the webassembly and passes the results back. In addition, these extra layers of abstraction will probably make debugging errors more difficult.

@tmpfs tmpfs self-assigned this Mar 29, 2023
@livingrockrises
Copy link

livingrockrises commented Oct 4, 2023

Hi guys! I noticed in this snap structure is bit different from general snap anatomy (https://docs.metamask.io/snaps/concepts/anatomy/). Is there any reason or benefit of it?
What is the advantage/need of having separate web assembly package?

Thank you!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants