near / nearcore

Reference client for NEAR Protocol
https://near.org
GNU General Public License v3.0
2.31k stars 614 forks source link

near-vm: Separate stack for VM executables #8962

Open nagisa opened 2 years ago

nagisa commented 2 years ago

Currently wasmer executes the code on the primary stack. This presents a couple of problems – there's some non-determinism due to the native stacks not having a deterministic size (glibc provides 8MB, Windows provides 1MB, musl may provide less space than even that by default) as described here.

We should ensure at least some semblance of deterministic execution by allocating, and switching to, a separate stack for VM execution. The stack may need to be switched back when calling a host function.

Relevant libraries here are stacker and psm.

matklad commented 2 years ago

To play a devil's advocate, host functions are going to use the native stack anyway, so making deterministic stack just for WASM doesn't entirely solve the problem. And, if the host needs to care that there's at least some stack left for host function calls, we can as well ask "and please make sure there's at least 1meg extra for wasm stack", or something along those lines. That is, I think it might be fine to push the responsibility of making sure that there's enough stack to the caller.

OTOH, it looks like we might want to setup a bigger stack & guard pages than 8MB anyway.

The stack may need to be switched back when calling a host function.

What would be the reasons to do that?

nagisa commented 2 years ago

What would be the reasons to do that?

We have little control over the codegen of the host functions, and in turn their stack usage is way less deterministic between even compilations of the same neard codebase than we'd like. This, in turn, can result in the guard pages being hit on some validators but not the others as a result of calling a host function.