dfinity-side-projects / wasm-persist

a JS module for creating orthogonally persistent WebAssembly instances
Mozilla Public License 2.0
41 stars 2 forks source link

Intra-call persistence? #6

Open void4 opened 6 years ago

void4 commented 6 years ago

Do you know if it is possible to save the call stack and heap within an imported Javascript function (such as usegas)? I'd like to combine gas based state snapshots with a merkle-tree-stream to achieve a truebit-like setup.

wanderer commented 6 years ago

no, unfortunately you cannot access wasm's native call stack. This only snapshots globals, memory(s), tables. I can't see how, off the top of my head how to do this with the native wasm implementation. But it might be possible with something like webassemblyjs

void4 commented 6 years ago

Yeah, it doesn't seem possible to inject a function that writes the stack to memory + another one to restore it from Wasm itself - and call these from the wasm-metering usegas function (since only the operand stack can be accessed and the call stack structure doesn't seem to be defined/accessible without something like resumable exceptions)

wanderer commented 6 years ago

yeah Algebraic Effect Handlers would be super sweet for this reason and others

rossberg commented 6 years ago

Just to clarify, even effect handlers would hardly give you the ability to persist a suspension. That would require complex machinery to persist arbitrary continuations as captured by a handler, which is extremely difficult to implement, would get in the way of all sorts of implementation techniques and optimisations inside VMs, and moreover, would likely open a huge attack vector for security exploits. I wouldn't expect this to ever happen.

void4 commented 6 years ago

@rossberg Stackless Python seems to show that it's achievable: http://stackless.readthedocs.io/en/2.7-slp/library/stackless/pickling.html The key seems to be to reify these structures only on demand and account for the relatively high cost of serialization with increased gas prices for the respective instructions. As long as Wasm stays side effect free and isolated, it might be possible to extend it with such functionality, for example by transforming arbitrary .wasm files to use/mirror a memory based stack. I absolutely agree that this will have a non-negligible resource overhead.

Right now I only see these three ways to achieve this property:

rossberg commented 6 years ago

Stackless Python is a high-level implementation of a high-level language operating in a closed-world execution environment. It has the liberty to use implementation techniques that are not an option for a low-level machine like Wasm, nor when you want full interoperability with arbitrary host environments or near-native execution speed.

I think your second option is probably the least bad option. But I don't know what the cost of that would be nor whether it will work with all future features of Wasm. To be honest, I am very skeptical that a heavy-handed approach like persisting arbitrary continuations is an advisable route altogether. ;)