refactor the transport constructor code to remove TransportWithOptions

This commit is contained in:
Marten Seemann 2022-11-08 18:00:32 +00:00
parent 479dbb93c4
commit 7d0b6ba933
2 changed files with 61 additions and 10 deletions

View File

@ -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),

View File

@ -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
}
}