From 9c61c6497a0062b8161f0a33f4368949c6b2ed4b Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 8 Nov 2022 18:00:32 +0000 Subject: [PATCH] refactor the transport constructor code to remove TransportWithOptions --- libp2p_test.go | 29 +++++++++++++++++++++++++++++ options.go | 42 ++++++++++++++++++++++++++++++++---------- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/libp2p_test.go b/libp2p_test.go index 8e70eef3c5..97b07d7fb2 100644 --- a/libp2p_test.go +++ b/libp2p_test.go @@ -12,10 +12,13 @@ import ( "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/transport" + "github.com/libp2p/go-libp2p/p2p/net/swarm" "github.com/libp2p/go-libp2p/p2p/security/noise" tls "github.com/libp2p/go-libp2p/p2p/security/tls" + quic "github.com/libp2p/go-libp2p/p2p/transport/quic" "github.com/libp2p/go-libp2p/p2p/transport/tcp" + ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" ) @@ -168,6 +171,32 @@ func TestChainOptions(t *testing.T) { } } +func TestTransportConstructorTCP(t *testing.T) { + h, err := New( + Transport(tcp.NewTCPTransport), + DisableRelay(), + ) + require.NoError(t, err) + defer h.Close() + require.NoError(t, h.Network().Listen(ma.StringCast("/ip4/127.0.0.1/tcp/0"))) + err = h.Network().Listen(ma.StringCast("/ip4/127.0.0.1/udp/0/quic")) + require.Error(t, err) + require.Contains(t, err.Error(), swarm.ErrNoTransport.Error()) +} + +func TestTransportConstructorQUIC(t *testing.T) { + h, err := New( + Transport(quic.NewTransport), + DisableRelay(), + ) + require.NoError(t, err) + defer h.Close() + require.NoError(t, h.Network().Listen(ma.StringCast("/ip4/127.0.0.1/udp/0/quic"))) + err = h.Network().Listen(ma.StringCast("/ip4/127.0.0.1/tcp/0")) + require.Error(t, err) + require.Contains(t, err.Error(), swarm.ErrNoTransport.Error()) +} + func TestSecurityConstructor(t *testing.T) { h, err := New( Transport(tcp.NewTCPTransport), diff --git a/options.go b/options.go index 00246ba82e..56538eba48 100644 --- a/options.go +++ b/options.go @@ -4,8 +4,11 @@ package libp2p // those are in defaults.go). import ( + "crypto/rand" + "encoding/binary" "errors" "fmt" + "reflect" "time" "github.com/libp2p/go-libp2p/config" @@ -124,23 +127,42 @@ func Muxer(name string, muxer network.Multiplexer) Option { // * Public Key // * Address filter (filter.Filter) // * Peerstore -func Transport[F any](tpt F) Option { +func Transport(constructor interface{}, opts ...interface{}) Option { return func(cfg *Config) error { + // generate a random identifier, so that fx can associate the constructor with its options + b := make([]byte, 8) + rand.Read(b) + id := binary.BigEndian.Uint64(b) + + tag := fmt.Sprintf(`group:"transportopt_%d"`, id) + + typ := reflect.ValueOf(constructor).Type() + numParams := typ.NumIn() + isVariadic := typ.IsVariadic() + var params []string + if isVariadic && len(opts) > 0 { + // If there are transport options, apply the tag. + // Since options are variadic, they have to be the last argument of the constructor. + params = make([]string, numParams) + params[len(params)-1] = tag + } + cfg.Transports = append(cfg.Transports, fx.Provide( fx.Annotate( - tpt, + constructor, + fx.ParamTags(params...), fx.As(new(transport.Transport)), fx.ResultTags(`group:"transport"`), ), )) - return nil - } -} - -func TransportWithOptions[F any, Opt any](tpt F, opts ...Opt) Option { - return func(cfg *Config) error { - cfg.Transports = append(cfg.Transports, fx.Provide(fx.Annotate(tpt, fx.ResultTags(`group:"transport"`)))) - cfg.Transports = append(cfg.Transports, fx.Supply(opts)) + for _, opt := range opts { + cfg.Transports = append(cfg.Transports, fx.Supply( + fx.Annotate( + opt, + fx.ResultTags(tag), + ), + )) + } return nil } }