bytecodealliance / wasmtime

A fast and secure runtime for WebAssembly
https://wasmtime.dev/
Apache License 2.0
15.44k stars 1.31k forks source link

import has the wrong type, but doesn't seem to be adapter version mismatch #7923

Closed sporkmonger closed 5 months ago

sporkmonger commented 9 months ago

Similar to #7505, I'm running into a problem with a "has the wrong type" error, but unlike that previous issue, I believe I do have the correct adapter version. I'm running wasmtime 17.0.1 with the reactor adapter taken from the corresponding release.

AnyError(import `wasi:http/types@0.2.0` has the wrong type

Caused by:
    0: instance export `incoming-request` has the wrong type
    1: expected resource found nothing))
$ wasm-tools component wit test_plugin.wasm          
package root:component;

world root {
  import wasi:io/error@0.2.0;
  import wasi:io/streams@0.2.0;
  import wasi:http/types@0.2.0;
  import bulwark:plugin/types@0.5.0;
  import wasi:cli/environment@0.2.0;
  import wasi:cli/exit@0.2.0;
  import wasi:cli/stdin@0.2.0;
  import wasi:cli/stdout@0.2.0;
  import wasi:cli/stderr@0.2.0;
  import wasi:clocks/wall-clock@0.2.0;
  import wasi:filesystem/types@0.2.0;
  import wasi:filesystem/preopens@0.2.0;
  import wasi:random/random@0.2.0;

  export bulwark:plugin/http-handlers@0.5.0;
}

I'm not particularly confident in the correctness of any of these, even though everything compiles OK:

However, I did have this previously working with a simpler API definition that didn't really try to do anything with WASI beyond using stdout/stderr.

Full codebase in this branch, along with wit definitions: https://github.com/bulwark-security/bulwark/tree/api-refactor

Unfortunately, I've exhausted everything I can think of to debug this. The error message just doesn't give a whole lot to go on and I'm wondering if there might be something that could be done to significantly improve that error message, because it has seemed to come up a lot.

pchickey commented 9 months ago

I think you are missing an add_to_linker that provides wasi:http/types here: https://github.com/bulwark-security/bulwark/compare/main...api-refactor#diff-3f2325fd7fe144935eb0a48fb3ced5e8afd4a3cc28a6ac7d86a629db1af865ccR282

This one will provide it, if you need the outgoing-handler as well that is nearby https://docs.rs/wasmtime-wasi-http/latest/wasmtime_wasi_http/bindings/wasi/http/types/fn.add_to_linker.html

sporkmonger commented 9 months ago

Wow, thanks, at first glance, that does indeed seem to have been the issue. I think I do need the outgoing-handler one too, but interestingly, omitting it doesn't seem to have failed anything on instantiation. Not sure I understand why the http types one would fail on instantiation but outgoing-handler wouldn't?

I'm also really interested in understanding your thought process for how you found the problem so quickly because I've been trying to figure it out for the better part of a week. 😬

Even with a likely root cause now, I think I feel like my comment on the error message still applies. This feels like a good opportunity to give implementors more useful information.

sporkmonger commented 9 months ago

Just noticed that wasm-tools component wit test_plugin.wasm output shows import wasi:http/types@0.2.0 but not import wasi:http/outgoing-handler@0.2.0, so presuming that's why... but I guess I'm not sure I understand why it's missing. Shouldn't the include have pulled it in?

pchickey commented 9 months ago

My thought process was: if its just HTTP that gets the complaint and not the rest of WASI, then you probably just weren't aware that our HTTP implementation lives in a separate crate. Missed add_to_linker is a sizable minority of the bug reports we get, so thats always one of the first things I rule out.

I don't see exactly where you performed an include - link me if you can.

If you did an include wasi:http/proxy; that should have pulled in the outgoing-handler import, and require an incoming-handler export be present. That's what we'd expect you to use if you were trying to provide a superset of the proxy world (meaning a proxy component that doesnt know anything about bulwark would execute just like it does in plain old wasmtime serve).

sporkmonger commented 9 months ago

This include: https://github.com/bulwark-security/bulwark/blob/api-refactor/wit/platform.wit#L4

pchickey commented 9 months ago

I took a look but I'm having a hard time getting oriented to reproduce - can you describe how to build the sample guest code, and run the host code, at the current commit?

sporkmonger commented 9 months ago

Getting a working build might require a new pull since I've made a few changes and fixes in the interim.

Normal build step for the main bulwark-cli binary (I usually just do cargo install --path .), then using that in the crates/wasm-sdk/examples/blank-slate directory to do its own build:

$ bulwark-cli build
[snip]
    Finished release [optimized] target(s) in 9.23s
$ wasm-tools component wit dist/plugins/bulwark_blank_slate.wasm
package root:component;

world root {
  import wasi:io/error@0.2.0;
  import wasi:io/streams@0.2.0;
  import wasi:http/types@0.2.0;
  import bulwark:plugin/types@0.5.0;
  import wasi:cli/environment@0.2.0;
  import wasi:cli/exit@0.2.0;
  import wasi:cli/stdin@0.2.0;
  import wasi:cli/stdout@0.2.0;
  import wasi:cli/stderr@0.2.0;
  import wasi:clocks/wall-clock@0.2.0;
  import wasi:filesystem/types@0.2.0;
  import wasi:filesystem/preopens@0.2.0;
  import wasi:random/random@0.2.0;

  export bulwark:plugin/http-handlers@0.5.0;
}

I was expecting to see import wasi:http/outgoing-handler@0.2.0 in there but it's missing.

alexcrichton commented 9 months ago

I'll note that when creating a component if an interface isn't used it'll be omitted from the final component. To that end can you confirm that dist/plugins/bulwark_blank_slate.wasm is using wasi:http/outgoing-handler? If it's not then that's expected behavior that the import doesn't show up, but if it is then something indeed odd is happening!

sporkmonger commented 5 months ago

Sorry, looping back to this quite a bit later. Yeah, that might be it. That specific component isn't using wasi:http/outgoing-handler. I'll have to write one that does and re-check. Might be working as intended!

sporkmonger commented 5 months ago

Confirmed, once I recompiled a component that used wasi:http/outgoing-handler it started to show up.

alexcrichton commented 5 months ago

Ok sounds good, thanks for the follow-up! I think that means everything here is working as expected, so I'm going to close. (if I missed something though let me know)