Skip to content

Error in MadSim 0.1.3 src/net/rpc.rs line 39 #2

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

Closed
BaldDemian opened this issue Feb 17, 2025 · 3 comments
Closed

Error in MadSim 0.1.3 src/net/rpc.rs line 39 #2

BaldDemian opened this issue Feb 17, 2025 · 3 comments

Comments

@BaldDemian
Copy link
Contributor

BaldDemian commented Feb 17, 2025

Thanks for providing these great labs! But I am not able to run the tests correctly on MacOS.
I try to run the test initial_election_2a, but found this compiling error

cargo test   
   Compiling madsim v0.1.3
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
  --> /Users/xxx/.cargo/registry/src/mirrors.ustc.edu.cn-4affec411d11e50f/madsim-0.1.3/src/net/rpc.rs:39:37
   |
39 |         let req_tag: u64 = unsafe { transmute(TypeId::of::<Req>()) };
   |                                     ^^^^^^^^^
   |
   = note: source type: `TypeId` (128 bits)
   = note: target type: `u64` (64 bits)

error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
  --> /Users/xxx/.cargo/registry/src/mirrors.ustc.edu.cn-4affec411d11e50f/madsim-0.1.3/src/net/rpc.rs:93:37
   |
93 |         let req_tag: u64 = unsafe { transmute(TypeId::of::<Req>()) };
   |                                     ^^^^^^^^^
   |
   = note: source type: `TypeId` (128 bits)
   = note: target type: `u64` (64 bits)

For more information about this error, try `rustc --explain E0512`.
error: could not compile `madsim` (lib) due to 2 previous errors

For your reference, this is the original src/net/rpc.rs

use super::*;
use serde::{de::DeserializeOwned, Serialize};
use std::{
    any::{Any, TypeId},
    fmt::Debug,
    // convert::TryInto,
    future::Future,
    mem::transmute,
};

/// A message that can be sent over the network.
pub trait Message: Debug + Serialize + DeserializeOwned + Any + Send + Sync {}

impl<T: Debug + Serialize + DeserializeOwned + Any + Send + Sync> Message for T {}

impl NetLocalHandle {
    /// Call function on a remote host with timeout.
    pub async fn call_timeout<Req, Rsp>(
        &self,
        dst: SocketAddr,
        request: Req,
        timeout: Duration,
    ) -> io::Result<Rsp>
    where
        Req: Message,
        Rsp: Message,
    {
        crate::time::timeout(timeout, self.call(dst, request))
            .await
            .map_err(|_| io::Error::new(io::ErrorKind::TimedOut, "RPC timeout"))?
    }

    /// Call function on a remote host.
    pub async fn call<Req, Rsp>(&self, dst: SocketAddr, request: Req) -> io::Result<Rsp>
    where
        Req: Message,
        Rsp: Message,
    {
        let req_tag: u64 = unsafe { transmute(TypeId::of::<Req>()) };
        let rsp_tag = self.handle.rand.with(|rng| rng.gen::<u64>());
        // let mut data = flexbuffers::to_vec(request).unwrap();
        // data.extend_from_slice(&rsp_tag.to_ne_bytes()[..]);
        // self.send_to(dst, req_tag, &data).await?;
        self.send_to_raw(dst, req_tag, Box::new((rsp_tag, request)))
            .await?;
        let (rsp, from) = self.recv_from_raw(rsp_tag).await?;
        assert_eq!(from, dst);
        // let rsp = flexbuffers::from_slice(&rsp).unwrap();
        let rsp = *rsp.downcast::<Rsp>().expect("message type mismatch");
        Ok(rsp)
    }

    /// Add a RPC handler.
    ///
    /// # Example
    ///
    /// ```
    /// use madsim::{Runtime, net::NetLocalHandle};
    ///
    /// let runtime = Runtime::new();
    /// let addr1 = "0.0.0.1:1".parse().unwrap();
    /// let addr2 = "0.0.0.2:1".parse().unwrap();
    /// let host1 = runtime.local_handle(addr1);
    /// let host2 = runtime.local_handle(addr2);
    ///
    /// host1
    ///     .spawn(async move {
    ///         let net = NetLocalHandle::current();
    ///         net.add_rpc_handler(|x: u64| async move { x + 1 });
    ///         net.add_rpc_handler(|x: u32| async move { x + 2 });
    ///     })
    ///     .detach();
    ///
    /// let f = host2.spawn(async move {
    ///     let net = NetLocalHandle::current();
    ///
    ///     let rsp: u64 = net.call(addr1, 1u64).await.unwrap();
    ///     assert_eq!(rsp, 2u64);
    ///
    ///     let rsp: u32 = net.call(addr1, 1u32).await.unwrap();
    ///     assert_eq!(rsp, 3u32);
    /// });
    ///
    /// runtime.block_on(f);
    /// ```
    pub fn add_rpc_handler<Req, Rsp, AsyncFn, Fut>(&self, mut f: AsyncFn)
    where
        Req: Message,
        Rsp: Message,
        AsyncFn: FnMut(Req) -> Fut + Send + 'static,
        Fut: Future<Output = Rsp> + Send + 'static,
    {
        let req_tag: u64 = unsafe { transmute(TypeId::of::<Req>()) };
        let net = self.clone();
        crate::task::spawn(async move {
            loop {
                let (data, from) = net.recv_from_raw(req_tag).await.unwrap();
                let (rsp_tag, req) = *data
                    .downcast::<(u64, Req)>()
                    .expect("message type mismatch");
                // let (data, rsp_tag_bytes) = data.split_at(data.len() - 8);
                // let rsp_tag = u64::from_ne_bytes(rsp_tag_bytes.try_into().unwrap());
                // let req: Req = flexbuffers::from_slice(data).unwrap();
                let rsp_future = f(req);
                let net = net.clone();
                crate::task::spawn(async move {
                    let rsp = rsp_future.await;
                    // let data = flexbuffers::to_vec(rsp).unwrap();
                    net.send_to_raw(from, rsp_tag, Box::new(rsp)).await.unwrap();
                })
                .detach();
            }
        })
        .detach();
    }
}

My rustc version is 1.84.1 (e71f9a9a9 2025-01-27)
Thanks for your time and reply

@BaldDemian
Copy link
Contributor Author

Ok I finally figure this out!
In Rust >= 1.72.0, the size of struct TypeId is 128 bits, so the call of transmute fails. While in earlier versions, its size is 64 bits.
The following is the src code < 1.72.0 from core/src/any.rs line 668

pub struct TypeId {
    t: u64,
}

The following is the src code >= 1.72.0 from the same file
https://github.com/rust-lang/rust/blob/ce36a966c79e109dabeef7a47fe68e5294c6d71e/library/core/src/any.rs#L710
Related PR is rust-lang/rust#109953

If you come across the same issue while using MadSim < v0.2.0, you can downgrade your rustc version using following commands:

rustup install 1.70.0
rustup default 1.70.0

Maybe it is better to mention this in the README in MadRaft? I can help make a PR! @wangrunji0408

@wangrunji0408
Copy link
Member

Thank you for the troubleshooting! This project has been unmaintained for a while, so your contribution is greatly appreciated. Welcome PR!

@BaldDemian
Copy link
Contributor Author

BaldDemian commented Feb 18, 2025

Thank you for the troubleshooting! This project has been unmaintained for a while, so your contribution is greatly appreciated. Welcome PR!

I modify the README.md and open a PR

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

2 participants