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

Deriving NetworkBehaviour seems to be broken in 0.40.0 #2328

Closed
hamamo opened this issue Nov 7, 2021 · 6 comments
Closed

Deriving NetworkBehaviour seems to be broken in 0.40.0 #2328

hamamo opened this issue Nov 7, 2021 · 6 comments

Comments

@hamamo
Copy link

hamamo commented Nov 7, 2021

When switching to libp2p 0.40.0, I get the following kind of error for every NetworkBehaviour that I compose using #[derive(NetworkBehaviour]:

error[E0277]: the trait bound `(): From<PingEvent>` is not satisfied
  --> src/reputation_net/mod.rs:42:10
   |
42 | #[derive(NetworkBehaviour)]
   |          ^^^^^^^^^^^^^^^^ the trait `From<PingEvent>` is not implemented for `()`
   |
   = help: see issue #48214
   = note: this error originates in the derive macro `NetworkBehaviour` (in Nightly builds, run with -Z macro-backtrace for more info)

Is this a known issue with 0.40.0? There are a number of changes documented in the various CHANGELOGs related to NetworkBehaviour, but I haven't been able to pinpoint where exactly I could find out what I need to change to make my code working again.

@wngr
Copy link
Contributor

wngr commented Nov 7, 2021

I was running into a similar issue. Solution for me was to group all ignored member fields..

@hamamo
Copy link
Author

hamamo commented Nov 7, 2021

You mean putting them into a separate struct so that only one field is marked with #[behaviour(ignore)]?

That didn't work for me. Of course it's possible I misunderstood your approach.

@elenaf9
Copy link
Contributor

elenaf9 commented Nov 8, 2021

With issue #2190 / the associated PR #2214 the NetworkBehaviour derive macro was changed to per default set event_process to false. When it was set to true, it was expected that NetworkBehaviourEventProcess<T> was implemented for all behaviour events, and events were handled via that implementation.
Now that it is per default false, events are not handled through NetworkBehaviourEventProcess, but instead returned as SwarmEvent::Behaviour(event) when polling the swarm. The type of that event is with the attribute macro #[behaviour(out_event = "OutEvent")], per default it is (), and is expected that From<T> is implemented for it for the events of the inner behaviours (which I believe is what causes your error).
To solve this you have the following options:

  1. set the attribute macro event_process = true if you'd like to keep the old logic, e.g. as done here:
    #[derive(NetworkBehaviour)]
    #[behaviour(event_process = true)]
    struct MyBehaviour {
    floodsub: Floodsub,
    mdns: Mdns,
    }
  2. define some OutEvent, and implement From<T> for OutEvent for the behaviour events e.g. as it is done here:
    #[derive(NetworkBehaviour)]
    #[behaviour(out_event = "OutEvent")]
    struct MyBehaviour {
    floodsub: Floodsub,
    mdns: Mdns,
    // Struct fields which do not implement NetworkBehaviour need to be ignored
    #[behaviour(ignore)]
    #[allow(dead_code)]
    ignored_member: bool,
    }
    #[derive(Debug)]
    enum OutEvent {
    Floodsub(FloodsubEvent),
    Mdns(MdnsEvent),
    }
    impl From<MdnsEvent> for OutEvent {
    fn from(v: MdnsEvent) -> Self {
    Self::Mdns(v)
    }
    }
    impl From<FloodsubEvent> for OutEvent {
    fn from(v: FloodsubEvent) -> Self {
    Self::Floodsub(v)
    }
    }

    and poll events via Swarm::poll.

You can find more info on that in the docs: https://docs.rs/libp2p/0.40.0/libp2p/swarm/trait.NetworkBehaviour.html#deriving-networkbehaviour. Does this help?

@hamamo
Copy link
Author

hamamo commented Nov 8, 2021

Thank you very much, this indeed explains the situation well. I wasn't aware that the event_process setting could have this effect.

Will try with event_process = true (corrected after response) later today, and read up on whether setting out_event is an option for me.

@hamamo hamamo closed this as completed Nov 8, 2021
@elenaf9
Copy link
Contributor

elenaf9 commented Nov 8, 2021

@hamamo just to quickly correct myself: if you'd like to keep the old logic, you have to set it to event_process = true. I edited my above comment.

@hamamo
Copy link
Author

hamamo commented Nov 13, 2021

Looks like one last thing was confusing me - rust-analyzer has some checks beyond what cargo check does, and it complains with an add-reference-here notification (https://rust-analyzer.github.io/manual.html#add-reference-here) for each composed network behaviour at the #[derive(NetworkBehaviour)] line. Since cargo compiles the code without complaints now, and I'm too lazy to analyze the result of the macro expansion to find the real culprit, I'm leaving it at that :-)

sunsided added a commit to sunsided/rustchain that referenced this issue Nov 28, 2021
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

3 participants