-
Notifications
You must be signed in to change notification settings - Fork 6
Require that all transports be "fully featured" #21
Comments
Also, I believe this would allow us to more easily punt some decisions around QUIC down the road. |
That is also how js-libp2p is structured:
|
First, there's a glaring motivation I missed: different transports will need different arguments. For example, secure connections will need keys. That makes fixing this a priority (as-is, our transport interfaces won't cut it). Second, an alternative (preferred by @whyrusleeping) is to add transports for every level. That is,
This solves the problem of needing to be able to pass different arguments when creating connections at different levels without forcing every transport to be fully-featured. Users would be able to register any kind of transport and have it type-checked at registration time (not compile time but still better than checking on connect). Personally, I'm not a fan of introducing so many interfaces but this does solve the problem (and, arguably, makes it easier for programmers to develop new transports). |
The second approach is also much closer to what @marten-seemann has been doing |
Yeah, it just requires at least 6 more interfaces (*Dial, *Listen, *Transport, *Conn). However, I'm probably just lazy. |
@Stebalien: I'm not sure I understand your proposal. Can you explain? Composition might be hard to do. Take the pnet for example. Making this work for multiplex connections required a lot of changes: libp2p/go-libp2p-pnet#8. (Or maybe this is a bad example, since we can replace pnet by TLS 1.3 PSK mode anyway). |
Ignore the packet feature, that was just me trying to ensure we don't have to redesign this stuff when we get unreliable packet-based transports. First of all, for context, @whyrusleeping's proposal is to define multiple transport interfaces along with the associated Dialer/Listener/Conn interfaces (not shown): trait Transport interface {
// Intentionally vague...
// NOTE: this is why *something* needs to change. We need to be able to pass crypto stuff when constructing dialers/listeners for dialers/listeners that do crypto.
func Dialer(cryptoStuff CryptoOptions, lid peer.ID, laddr peer.ID, opts ...DialerOpt) Dialer
func Listener(cryptoStuff CryptoOptions, lid peer.ID, laddr peer.ID, opts ...ListenerOpt) Listener
func Matches(maddr Multiaddr) bool
}
trait SecureTransport interface {
func Dialer(cryptoStuff CryptoOptions, lid peer.ID, laddr peer.ID, opts ...SecureDialerOpt) DuplexDialer
func Listener(cryptoStuff CryptoOptions, lid peer.ID, laddr peer.ID, opts ...SecureListenerOpt) SecureListener
func Matches(maddr Multiaddr) bool
}
trait BasicTransport interface {
func Dialer(laddr peer.ID, opts ...BasicDialerOpt) BasicDialer
func Listener(laddr peer.ID, opts ...BasicListenerOpt) BasicListener
func Matches(maddr Multiaddr) bool
} Programmers would register their transports at start (probably in module-level My only real objection was that this needs 12 interfaces. An alternative that only requires 4 interfaces and no casting is to just define the In summary, Pros
Cons
Honestly, @whyrusleeping's approach is probably better in the long run (largely due to the second con). It just requires a bit more thought up-front (to get all the interfaces right).
I'm not sure I follow. What changes? |
this seems to be complicating a lot -- 12 interfaces is insane! |
State: In progress. Branch
Branch
Deprecated packages:
TODO:
(and probably more)
Known Bugs:
Hopefully this should give you an idea of what's going on if you want to jump in. With the exception of go-reuseport-transport, this code should be significantly cleaner and easier to understand (not having piles of bug fixes on top of piles of bug fixes helps quite a bit...). |
Note: We went with the original fully-featured transport proposal, not the many traits version. |
Moved to: libp2p/go-libp2p#297 |
This is an alternative to #17.
Instead of introspecting transports in https://github.com/libp2p/go-libp2p-conn to see what features they support, we can require that all transports support all features: pnet (pre-shared key), encryption/authentication (e.g., secio), multiplexing, (packets?). To avoid forcing every transport to implement all of these features, we can use composition. That is, provide a set of helper types/functions that can be used to plugin in default implementations of these features.
This:
The large drawback here is backwards compatibility with old transports (adding a new feature means changing existing transports). However, this will often be the case anyways if we want to be able to pass in new parameters when we construct connections (unless we version the dial functions but, IMO, that's no better).
The text was updated successfully, but these errors were encountered: