Misc libp2p questions around protocol definition, stream reuse and data verification

Hi, I was just going through the source code of libp2p example at https://github.com/libp2p/go-libp2p-examples/tree/master/multipro and had the following questions around best practices, would appreciate some help since I’m relatively new to this:

  1. In the example (https://github.com/libp2p/go-libp2p-examples/blob/95f2810c563649d7b8ad940eda4be801c381e63a/multipro/ping.go#L16-L18), we defined separate protocols for request and response (where each message has its own protobuf message definition), whereas in previous examples the same protocol is being used for both the request and response. So I wonder is it the best practice for a libp2p application to define separate protocols for its request and response? or using a single protocol with a single protobuf message schema?

  2. In the example (https://github.com/libp2p/go-libp2p-examples/blob/master/multipro/node.go#L142-L143), when sending back the response a new stream is initiated instead of reusing the inbound stream for writing the response back. My question is in general, when should we reuse vs. initate new stream?

  3. Related to No.2, what would be the best practice for a libp2p application to manage request-response pairs? In the example, it manages a map of requests, but if we just reuse the same stream (meaning no need for response handler) then we don’t really need to maintain information like request ids and could just read from the same stream to know that it’s for the request that was sent through the same stream?

  4. Related to No.2 and No.3, is there any automatic Stream-level reuse? Or is Stream meant to live no longer than a request-response cycle? based on the source code it doesn’t seem to be the case where it just grabs the best existing Connection with the peer and creates a new stream on top of it https://github.com/libp2p/go-libp2p-swarm/blob/58c167a7b0c3294d416342d781465214d514e70f/swarm.go#L318-L363

  5. The example (https://github.com/libp2p/go-libp2p-examples/blob/master/multipro/node.go#L41-L118) added data signing and verification as part of its own protocol message interpretation logic, but I wonder if there’s any built-in functionality/utility for this in libp2p itself since I feel like the workflow would be relatively standard when it comes to verifying message integrity?

Thanks in advance to anyone who has the patience to read through and help answer those questions!