Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The trait is not implemented for T ERROR #10125

Open
celinesantosh98 opened this issue Jan 27, 2025 · 0 comments
Open

The trait is not implemented for T ERROR #10125

celinesantosh98 opened this issue Jan 27, 2025 · 0 comments

Comments

@celinesantosh98
Copy link

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:[email protected];

interface tcp{
  
  
  use wasi:sockets/[email protected].{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/[email protected];
  import wasi:sockets/[email protected];
  import wasi:sockets/[email protected];
  include wasi:cli/[email protected];
  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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant