warp-contracts/warp

[BUG] Uncaught Exception when reading some Rust contracts

balthazar opened this issue · 1 comments

Rust contracts appear to be able to throw uncaught exceptions

RuntimeError: unreachable
    at wasm://wasm/0018e00e:wasm-function[241]:0x49619
    at wasm://wasm/0018e00e:wasm-function[323]:0x55df5
    at wasm://wasm/0018e00e:wasm-function[268]:0x4f511
    at wasm://wasm/0018e00e:wasm-function[37]:0x1b75a
    at wasm://wasm/0018e00e:wasm-function[26]:0xd0d8
    at wasm://wasm/0018e00e:wasm-function[30]:0x13197
    at wasm://wasm/0018e00e:wasm-function[27]:0xf737
    at wasm://wasm/0018e00e:wasm-function[197]:0x44484
    at wasm://wasm/0018e00e:wasm-function[352]:0x56a00
    at __wbg_adapter_52 (node_modules/warp-contracts/lib/cjs/core/modules/impl/wasm/rust-wasm-imports.js:323:38)

Some examples:

  • orylAfmrE2P3KilCcpY1BlCgds81kNzyYkt8Gtaj8cU
  • SneNixa6opQ1Faa3UMDRbjMvcwlaoqE2t_uiBqd6QE4
  • Ogjc4b5uWhbNvhtZA4zgVu3QtgO0AXEY48CdKb7ubSM
  • FFScYUwUaVtUFTkgtrvjfvJj1D7PaF2KbGMZANxYky0
  • -rfe1sCsruhHUa4H656cPJ3Z-oSvRgE5APePyIcqdOI
  • 383IYmwLPXm1ibvGFPaiCqMeMWK50dFFAz8hjPX9wtg

I've done my own ugly fix to circumvent that behavior, but it would probably be a good idea to prevent it from happening in the first place and correctly reject the readState call with that error.

Specs:

  • OS: Amazon Linux 2
  • Node.js version: 18
  • warp-contracts SDK version: 1.4.9
  • plugins: warp-contracts-plugin-vm2@1.0.2 warp-contracts-sqlite@1.0.1

I'm afraid that for the 'old' contracts the only way to catch such erros (which effecitvely are 'panics' from the Rust) is to register a global handler.

The new Warp wasm contracts libraries (introduced somewhere around 03.2023) should have most of such issues fixed (these issues usually were caused by the serde not being able to map a javascript object into Rust structures (e.g. because of missing properties).

I'm not sure though if even the new implementation can handle random panics from any part of the contract code - we will need to verify this internally.

Some related issues:
rust-lang/rust#58874
https://users.rust-lang.org/t/catch-panic-in-wasm/57569
cloudflare/workers-rs#166
cloudflare/workers-rs#178

(a side note - obviously we have try-catch in JS around the code that calls the WASM functions - but it does not work in this case - probably for the reasons described in the above issues).

@asiaziola , can you please verify

  1. how the SDK will behave with some random panic in the contract (using the latest versions of the Warp crates, etc).
  2. if the SDK won't be able to catch the error from panic - check if adding std::panic::catch_unwind around the panic solves the issue (if not, we're fu*ked :-))