As of today, wasmtime has implemented:
- bulk memory operations
- memory64
- multi-memory
The first is fully standardized. The latter two are in a late stage of standardization. IMO it’s only a matter of time (i.e. 1-2 years) before they are fully standardized.
In Motoko, stable memory is accessed either via stable variables or via the new ExperimentalStableMemory library.
The first is dev-friendly and fast, but requires annoying (and expensive) preupgrade and postupgrade hooks to copy data from IC’s stable memory to the canister wasm’s linear memory (and vice versa). Of course, that means this is limited by a canister wasm’s linear memory, which is currently 4 GB. (In reality, it’s less, closer to 2 GB or 3 GB depending on the Motoko GC you use during compilation.) These hooks can also trap if they hit a cycle limit, which is bad.
The second is safe and gives access to more storage, up to 300 GB supposedly. But it’s not dev-friendly at all. You have to manually convert high-level data structures like Tries into low-level reads and writes on primitives like Nat32 and Blob. It’s also slower at runtime due to System API calls, but as a result also requires no preupgrade and postupgrade hooks. Unfortunately, it’s also marked as experimental so probably not safe to rely on long-term.
I’m wondering what the plan is regarding stable memory in 2022, given the recent developments in wasmtime. I’m especially curious about Motoko, which is what I use.
Stable memory is really important. Almost all canisters will need to be upgraded at some point, so most data on the IC actually needs to be stored in stable memory.
My understanding from reading this thread is that the best way forward is to:
- Store stable memory (which is 64-bit) in a separate 64-bit wasm memory, which is now possible due to wasmtime having implemented memory64 and multi-memory
- Amend the System API (or other low-level IC interface) to allow that new wasm memory to cheaply “persist” to IC stable memory, without relying on expensive System API calls through the existing stable memory interface (e.g.
ic0.stable64_read
) - Implement cross-memory garbage collection, which is necessary in a high-level language like Motoko
Does that sound right? If so, is this on the roadmap for this year?
Dealing with storage on the IC is perhaps the biggest headache I’ve encountered while developing. It’d be great to have a more unified interface to stable memory, without having to worry about a bunch of gotchas (that are typically gleaned from some post hidden in some thread).
Thank you!