diff --git a/config/config.go b/config/config.go index 07bee93c60..fb5a2ab1b1 100644 --- a/config/config.go +++ b/config/config.go @@ -36,6 +36,7 @@ import ( circuitv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client" relayv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay" "github.com/libp2p/go-libp2p/p2p/protocol/holepunch" + "github.com/libp2p/go-libp2p/p2p/protocol/identify" "github.com/libp2p/go-libp2p/p2p/transport/quicreuse" libp2pwebrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc" "github.com/prometheus/client_golang/prometheus" @@ -142,6 +143,8 @@ type Config struct { CustomUDPBlackHoleSuccessCounter bool IPv6BlackHoleSuccessCounter *swarm.BlackHoleSuccessCounter CustomIPv6BlackHoleSuccessCounter bool + + UserFxOptions []fx.Option } func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (*swarm.Swarm, error) { @@ -482,6 +485,9 @@ func (cfg *Config) NewNode() (host.Host, error) { return sw, nil }), fx.Provide(cfg.newBasicHost), + fx.Provide(func(bh *bhost.BasicHost) identify.IDService { + return bh.IDService() + }), fx.Provide(func(bh *bhost.BasicHost) host.Host { return bh }), @@ -536,6 +542,8 @@ func (cfg *Config) NewNode() (host.Host, error) { fxopts = append(fxopts, fx.Invoke(func(bho *routed.RoutedHost) { rh = bho })) } + fxopts = append(fxopts, cfg.UserFxOptions...) + app := fx.New(fxopts...) if err := app.Start(context.Background()); err != nil { return nil, err diff --git a/fx_options_test.go b/fx_options_test.go new file mode 100644 index 0000000000..48ac79b53d --- /dev/null +++ b/fx_options_test.go @@ -0,0 +1,60 @@ +package libp2p + +import ( + "testing" + + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/p2p/protocol/identify" + "github.com/stretchr/testify/require" + "go.uber.org/fx" +) + +func TestGetPeerID(t *testing.T) { + var id peer.ID + host, err := New( + WithFxOption(fx.Populate(&id)), + ) + require.NoError(t, err) + defer host.Close() + + require.Equal(t, host.ID(), id) + +} + +func TestGetEventBus(t *testing.T) { + var eb event.Bus + host, err := New( + NoTransports, + WithFxOption(fx.Populate(&eb)), + ) + require.NoError(t, err) + defer host.Close() + + require.NotNil(t, eb) +} + +func TestGetHost(t *testing.T) { + var h host.Host + host, err := New( + NoTransports, + WithFxOption(fx.Populate(&h)), + ) + require.NoError(t, err) + defer host.Close() + + require.NotNil(t, h) +} + +func TestGetIDService(t *testing.T) { + var id identify.IDService + host, err := New( + NoTransports, + WithFxOption(fx.Populate(&id)), + ) + require.NoError(t, err) + defer host.Close() + + require.NotNil(t, id) +} diff --git a/options.go b/options.go index 8e720137c0..4fbf8eb2ac 100644 --- a/options.go +++ b/options.go @@ -634,3 +634,12 @@ func IPv6BlackHoleSuccessCounter(f *swarm.BlackHoleSuccessCounter) Option { return nil } } + +// WithFxOption adds a user provided fx.Option to the libp2p constructor. +// Experimental: This option is subject to change or removal. +func WithFxOption(opts ...fx.Option) Option { + return func(cfg *Config) error { + cfg.UserFxOptions = append(cfg.UserFxOptions, opts...) + return nil + } +}