Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(modp2p): websocket transport with TLS #3560

Merged
merged 14 commits into from
Aug 6, 2024
6 changes: 3 additions & 3 deletions nodebuilder/p2p/addrs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
)

// Listen returns invoke function that starts listening for inbound connections with libp2p.Host.
func Listen(listen []string) func(h hst.Host) (err error) {
func Listen(cfg *Config) func(h hst.Host) (err error) {
return func(h hst.Host) (err error) {
maListen := make([]ma.Multiaddr, len(listen))
for i, addr := range listen {
maListen := make([]ma.Multiaddr, len(cfg.ListenAddresses))
for i, addr := range cfg.ListenAddresses {
maListen[i], err = ma.NewMultiaddr(addr)
if err != nil {
return fmt.Errorf("failure to parse config.P2P.ListenAddresses: %w", err)
Expand Down
15 changes: 15 additions & 0 deletions nodebuilder/p2p/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,18 @@ func (cfg *Config) Validate() error {
}
return nil
}

// Upgrade updates the `ListenAddresses` and `NoAnnounceAddresses` to
// include support for websocket connections.
func (cfg *Config) Upgrade() {
cfg.ListenAddresses = append(
cfg.ListenAddresses,
"/ip4/0.0.0.0/tcp/2122/wss",
"/ip6/::/tcp/2122/wss",
)
cfg.NoAnnounceAddresses = append(
cfg.NoAnnounceAddresses,
"/ip4/127.0.0.1/tcp/2122/wss",
"/ip6/::/tcp/2122/wss",
)
}
20 changes: 19 additions & 1 deletion nodebuilder/p2p/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import (
"github.com/libp2p/go-libp2p/core/routing"
routedhost "github.com/libp2p/go-libp2p/p2p/host/routed"
"github.com/libp2p/go-libp2p/p2p/net/conngater"
quic "github.com/libp2p/go-libp2p/p2p/transport/quic"
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
webtransport "github.com/libp2p/go-libp2p/p2p/transport/webtransport"
"github.com/prometheus/client_golang/prometheus"
"go.uber.org/fx"

Expand Down Expand Up @@ -67,6 +70,15 @@ func (ua *UserAgent) String() string {
func host(params hostParams) (HostBase, error) {
ua := newUserAgent().WithNetwork(params.Net).WithNodeType(params.Tp)

tlsCfg, isEnabled, err := tlsEnabled()
if err != nil {
return nil, err
}

if isEnabled {
params.Cfg.Upgrade()
}

opts := []libp2p.Option{
libp2p.NoListenAddrs, // do not listen automatically
libp2p.AddrsFactory(params.AddrF),
Expand All @@ -79,9 +91,14 @@ func host(params hostParams) (HostBase, error) {
libp2p.DisableRelay(),
libp2p.BandwidthReporter(params.Bandwidth),
libp2p.ResourceManager(params.ResourceManager),
libp2p.ChainOptions(
libp2p.Transport(tcp.NewTCPTransport),
libp2p.Transport(quic.NewTransport),
libp2p.Transport(webtransport.New),
wsTransport(tlsCfg),
),
// to clearly define what defaults we rely upon
libp2p.DefaultSecurity,
libp2p.DefaultTransports,
libp2p.DefaultMuxers,
}

Expand Down Expand Up @@ -113,6 +130,7 @@ type HostBase hst.Host
type hostParams struct {
fx.In

Cfg *Config
Net Network
Lc fx.Lifecycle
ID peer.ID
Expand Down
2 changes: 1 addition & 1 deletion nodebuilder/p2p/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func defaultConnManagerConfig(tp node.Type) connManagerConfig {
}

// connectionManager provides a constructor for ConnectionManager.
func connectionManager(cfg Config, bpeers Bootstrappers) (connmgri.ConnManager, error) {
func connectionManager(cfg *Config, bpeers Bootstrappers) (connmgri.ConnManager, error) {
fpeers, err := cfg.mutualPeers()
if err != nil {
return nil, err
Expand Down
5 changes: 2 additions & 3 deletions nodebuilder/p2p/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ var log = logging.Logger("module/p2p")
func ConstructModule(tp node.Type, cfg *Config) fx.Option {
// sanitize config values before constructing module
cfgErr := cfg.Validate()

baseComponents := fx.Options(
fx.Supply(*cfg),
fx.Error(cfgErr),
fx.Supply(cfg),
fx.Provide(Key),
fx.Provide(id),
fx.Provide(peerStore),
Expand All @@ -34,7 +33,7 @@ func ConstructModule(tp node.Type, cfg *Config) fx.Option {
fx.Provide(addrsFactory(cfg.AnnounceAddresses, cfg.NoAnnounceAddresses)),
fx.Provide(metrics.NewBandwidthCounter),
fx.Provide(newModule),
fx.Invoke(Listen(cfg.ListenAddresses)),
fx.Invoke(Listen(cfg)),
fx.Provide(resourceManager),
fx.Provide(resourceManagerOpt(allowList)),
)
Expand Down
4 changes: 2 additions & 2 deletions nodebuilder/p2p/pubsub.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func init() {
}

// pubSub provides a constructor for PubSub protocol with GossipSub routing.
func pubSub(cfg Config, params pubSubParams) (*pubsub.PubSub, error) {
func pubSub(cfg *Config, params pubSubParams) (*pubsub.PubSub, error) {
fpeers, err := cfg.mutualPeers()
if err != nil {
return nil, err
Expand Down Expand Up @@ -122,7 +122,7 @@ func topicScoreParams(params pubSubParams) map[string]*pubsub.TopicScoreParams {
return mp
}

func peerScoreParams(bootstrappers Bootstrappers, cfg Config) (*pubsub.PeerScoreParams, error) {
func peerScoreParams(bootstrappers Bootstrappers, cfg *Config) (*pubsub.PeerScoreParams, error) {
bootstrapperSet := map[peer.ID]struct{}{}
for _, b := range bootstrappers {
bootstrapperSet[b.ID] = struct{}{}
Expand Down
2 changes: 1 addition & 1 deletion nodebuilder/p2p/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func autoscaleResources() rcmgr.ConcreteLimitConfig {
return limits.AutoScale()
}

func allowList(ctx context.Context, cfg Config, bootstrappers Bootstrappers) (rcmgr.Option, error) {
func allowList(ctx context.Context, cfg *Config, bootstrappers Bootstrappers) (rcmgr.Option, error) {
mutual, err := cfg.mutualPeers()
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion nodebuilder/p2p/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func contentRouting(r routing.PeerRouting) routing.ContentRouting {

// peerRouting provides constructor for PeerRouting over DHT.
// Basically, this provides a way to discover peer addresses by respecting public keys.
func peerRouting(cfg Config, tp node.Type, params routingParams) (routing.PeerRouting, error) {
func peerRouting(cfg *Config, tp node.Type, params routingParams) (routing.PeerRouting, error) {
opts := []dht.Option{
dht.Mode(dht.ModeAuto),
dht.BootstrapPeers(params.Peers...),
Expand Down
51 changes: 51 additions & 0 deletions nodebuilder/p2p/tls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package p2p

import (
"crypto/tls"
"os"
"path/filepath"

"github.com/libp2p/go-libp2p"
ws "github.com/libp2p/go-libp2p/p2p/transport/websocket"

"github.com/celestiaorg/celestia-node/libs/utils"
)

const (
cert = "cert.pem"
key = "key.pem"
)

var tlsPath = "CELESTIA_TLS_PATH"

// tlsEnabled checks whether `tlsPath` is not empty and creates a certificate.
// it returns the cfg itself, the bool flag that specifies whether the config was created
// and an error.
func tlsEnabled() (*tls.Config, bool, error) {
path := os.Getenv(tlsPath)
certPath := filepath.Join(path, cert)
keyPath := filepath.Join(path, key)

exist := utils.Exists(certPath) && utils.Exists(keyPath)
if !exist {
return nil, false, nil
}

var certificates []tls.Certificate
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
if err != nil {
return nil, false, err
}
certificates = append(certificates, cert)
return &tls.Config{MinVersion: tls.VersionTLS12, Certificates: certificates}, true, nil
}

// wsTransport enables a support for the secure websocket connection
// using the passed tls config. The connection will be insecure in case
// config is empty.
func wsTransport(config *tls.Config) libp2p.Option {
if config == nil {
return libp2p.Transport(ws.New)
}
return libp2p.Transport(ws.New, ws.WithTLSConfig(config))
}
2 changes: 1 addition & 1 deletion state/core_access.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ func (ca *CoreAccessor) setupTxClient(ctx context.Context, keyName string) (*use
}
ca.defaultSignerAddress = addr
return user.SetupTxClient(ctx, ca.keyring, ca.coreConn, encCfg,
user.WithDefaultAccount(keyName), user.WithDefaultAddress(addr),
user.WithDefaultAccount(keyName),
)
}

Expand Down
Loading