Stream: git-wasmtime

Topic: wasmtime / issue #10125 The trait is not implemented for...


view this post on Zulip Wasmtime GitHub notifications bot (Jan 27 2025 at 18:50):

celinesantosh98 opened issue #10125:

Hi,

I am trying to intercept the wasi call start-connect in wasi:sockets/tcp. I am planning to put all wasi calls except wasi:sockets/tcp into the linker and create a custom implementation say mwasi:sockets/tcp and implement my custom start-connect , for now I am writing a print statement.
So I have created a host embedding which I implemented. Then I have a random go_app which simply makes tcp connection, I have used WASI API calls start-connect for making tcp call because afaik ,go hasn't implemented the sockets yet. Then I have wit file .

host embedding:

use wasmtime::{Engine, Result, Store, Config};
use wasmtime::component::{ Linker, Component};
use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiView, ResourceTable};
use wasmtime_wasi::WasiImpl;
use std::sync::{Arc, Mutex};
use anyhow::{Context};
use wasmtime::component::bindgen;

use wasmtime_wasi::bindings::sockets::network::{Network, ErrorCode, IpSocketAddress, IpAddressFamily};
use std::net::SocketAddr;
use wasmtime_wasi::SocketResult;
use wasmtime_wasi::bindings::sockets::tcp_create_socket::Host;
//use crate::wasi::sockets::{tcp_create_socket, udp_create_socket};use wasmtime::component::Resource;
use wasmtime_wasi::SocketError;
// Bindgen the provided WIT

bindgen!({
    path: "wit",
    world: "wrapper",
    with: {
        "wasi": wasmtime_wasi::bindings,
    },
    require_store_data_send: true,
});
struct MyState {
    ctx: WasiCtx,
    table: ResourceTable,
}

impl WasiView for MyState {
    fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
    fn table(&mut self) -> &mut ResourceTable { &mut self.table }
}

fn type_annotate<T: WasiView, F>(val: F) -> F
where
    F: Fn(&mut T) -> WasiImpl<&mut T>,
{
    val
}
impl mwasi::sockets::tcp::Host for MyState {
     fn start_connect(&mut self, network:Resource<Network>, remote_address: IpSocketAddress) -> Result<(), ErrorCode> {
        println!("Intercepted TCP call: Printing from the monitor");
        println!("start-connect operation successful!");
        Ok(())
    }

}
pub fn add_to_linker_without_tcp<T: WasiView>(
    linker: &mut wasmtime::component::Linker<T>,
) -> anyhow::Result<()> {
    let l = linker;
    let closure = type_annotate::<T, _>(|t| WasiImpl(t));
    wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::sync::filesystem::types::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::filesystem::preopens::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::sync::io::poll::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::sync::io::streams::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::random::random::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::random::insecure::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::random::insecure_seed::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::cli::exit::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::cli::environment::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::cli::stdin::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::cli::stdout::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::cli::stderr::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::cli::terminal_input::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::cli::terminal_output::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::cli::terminal_stdin::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::cli::terminal_stdout::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::cli::terminal_stderr::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::sockets::tcp_create_socket::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::sync::sockets::udp::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::sockets::udp_create_socket::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::sockets::instance_network::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::sockets::network::add_to_linker_get_host(l, closure)?;
    wasmtime_wasi::bindings::sockets::ip_name_lookup::add_to_linker_get_host(l, closure)?;
    Wrapper::add_to_linker(l, |state: &mut T| state)?;
    Ok(())
}



fn main() -> Result<()> {

    //let engine = Engine::default();
    let mut config = Config::new();
    config.wasm_component_model(true);

    let engine = Engine::new(&config)?;
    let mut linker = Linker::<MyState>::new(&engine);


    let wasi_ctx = WasiCtxBuilder::new()
    .inherit_stdio()
    .inherit_env()
    .inherit_network()
    .allow_ip_name_lookup(true)
    .allow_tcp(true)
    .allow_udp(true)
    .build();

    let state = MyState {
                        ctx: wasi_ctx,
                        table: ResourceTable::new(),
                    };

    let mut store = Store::new(&engine, state);

    let app_component = Component::from_file(&engine, "go_app.wasm")
     .context("Failed to load Rust app")?;


    // Instantiate both components
    linker.instantiate(&mut store, &app_component)?;

     let bindings = Wrapper::instantiate(&mut store, &app_component, &linker)?;

    let command = wasmtime_wasi::bindings::sync::Command::instantiate(
            &mut store,
            &app_component,
            &linker,
        )?;
        let result = command
            .wasi_cli_run()
            .call_run(&mut store)
            .context("failed to invoke `run` function");
            //.map_err(|e| handle_core_dump(&mut store, e));

    Ok(())
}

Wit file

package mwasi:sockets@0.2.0;

interface tcp{


  use wasi:sockets/network@0.2.0.{network, error-code, ip-socket-address, ip-address-family};

  start-connect: func(network: borrow<network>, remote-address: ip-socket-address) -> result<_, error-code>;

}

world wrapper{
  import wasi:io/error@0.2.0;
  import wasi:sockets/tcp@0.2.0;
  import wasi:sockets/network@0.2.0;
  include wasi:cli/imports@0.2.0;
  import tcp;
}

go_app

package main

//go:generate go run github.com/bytecodealliance/wasm-tools-go/cmd/wit-bindgen-go generate --world go_app --out gen ../wit

import (
    "fmt"
    "log"

    //"go_app/src/gen/wasi/sockets/tcp"
    //mwasi_tcp "go_app/src/gen/mwasi/sockets/tcp"
    instancenetwork "go_app/src/gen/wasi/sockets/instance-network"
    "go_app/src/gen/wasi/sockets/network"
    tcpcreatesocket "go_app/src/gen/wasi/sockets/tcp-create-socket"
)

func main() {


    googleAddress := network.IPSocketAddressIPv4(network.IPv4SocketAddress{
        Address: network.IPv4Address{142, 250, 181, 206},
        Port:    80,
    })


    // Connect to Google.com
    fmt.Println("Connecting to Google.com...")
    err = connectToServer(googleAddress)
    if err != nil {
        log.Fatalf("Failed to connect to Google.com: %v", err)
    } else {
        fmt.Println("Connected to Google.com.")
    }
}

func connectToServer(address network.IPSocketAddress) error {
    // Get a handle to the default network
    netInstance := instancenetwork.InstanceNetwork()

    // Create a new TCP socket
    socketResult := tcpcreatesocket.CreateTCPSocket(network.IPAddressFamilyIPv4)
    if !socketResult.IsOK() {
        return fmt.Errorf("failed to create TCP socket: %v", socketResult.Err())
    }
    socket := socketResult.OK()


    // Start the connection
    connectResult := socket.StartConnect(netInstance, address)
    if !connectResult.IsOK() {
        return fmt.Errorf("start-connect failed: %v", connectResult.Err())
    }

I have the necessary's folder and go bindings in gen folder.
So the expected outcome is that it should print "Intercepted TCP call: Printing from the monitor" when app makes the network call. so then I can confirm the wasi call start-connect is intercepted.

But I am getting error

error[E0277]: the trait bound `T: wasmtime_wasi::bindings::random::insecure_seed::Host` is not satisfied
   --> src/main.rs:102:5
    |
102 |     Wrapper::add_to_linker(l, |state: &mut T| state)?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `wasmtime_wasi::bindings::random::insecure_seed::Host` is not implemented for `T`
    |
note: required by a bound in `_::<impl Wrapper>::add_to_linker`
   --> src/main.rs:21:1
    |
21  | / bindgen!({
22  | |     path: "wit",
23  | |     world: "wrapper",
24  | |     with: {
...   |
27  | |     require_store_data_send: true,
28  | | });
    | |__^ required by this bound in `_::<impl Wrapper>::add_to_linker`
    = note: this error originates in the macro `bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
    |
70  | pub fn add_to_linker_without_tcp<T: WasiView + wasmtime_wasi::bindings::random::insecure_seed::Host>(
    |                                              ++++++++++++++++++++++++++++++++++++++++++++++++++++++

I am getting 28 similar errors for each interface.
I have already given wasmtime_Wasi in the with clause of bindgen macro, then why is it giving me this error

view this post on Zulip Wasmtime GitHub notifications bot (Feb 03 2025 at 21:46):

celinesantosh98 edited issue #10125:

The issue is not relevant now, so had to delete it.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 27 2025 at 18:01):

fitzgen closed issue #10125:

The issue is not relevant now, so had to delete it.


Last updated: Feb 28 2025 at 02:27 UTC