Skip to content

Commit

Permalink
cmd/relay: serve multiaddrs from http address (#1646)
Browse files Browse the repository at this point in the history
Relay serves multiaddrs from http-address server.

category: feature
ticket: #1632
  • Loading branch information
corverroos authored Jan 18, 2023
1 parent 37363a1 commit 1b4c97c
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 9 deletions.
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ func wireP2P(ctx context.Context, life *lifecycle.Manager, conf Config,
}

// Start libp2p TCP node.
tcpNode, err := p2p.NewTCPNode(ctx, conf.P2P, p2pKey, connGater, conf.TestConfig.LibP2POpts...)
tcpNode, err := p2p.NewTCPNode(ctx, conf.P2P, p2pKey, connGater, conf.P2P.RelayDiscovery(), conf.TestConfig.LibP2POpts...)
if err != nil {
return nil, nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/relay/p2p.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func startP2P(ctx context.Context, config Config, key *ecdsa.PrivateKey, reporte
return nil, errors.Wrap(err, "new resource manager")
}

tcpNode, err := p2p.NewTCPNode(ctx, config.P2PConfig, key, p2p.NewOpenGater(),
tcpNode, err := p2p.NewTCPNode(ctx, config.P2PConfig, key, p2p.NewOpenGater(), true,
libp2p.ResourceManager(mgr), libp2p.BandwidthReporter(reporter))
if err != nil {
return nil, errors.Wrap(err, "new tcp node")
Expand Down
13 changes: 12 additions & 1 deletion cmd/relay/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package relay

import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/pprof"
Expand Down Expand Up @@ -109,9 +110,19 @@ func Run(ctx context.Context, config Config) error {
}

mux := http.NewServeMux()
mux.HandleFunc("/enr", func(w http.ResponseWriter, r *http.Request) {
mux.HandleFunc("/enr/", func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(localEnode.Node().String()))
})
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
b, err := json.Marshal(tcpNode.Addrs())
if err != nil {
log.Error(r.Context(), "Marshal multiaddrs", err)
w.WriteHeader(http.StatusInternalServerError)

return
}
_, _ = w.Write(b)
})
server := http.Server{Addr: config.HTTPAddr, Handler: mux, ReadHeaderTimeout: time.Second}
serverErr <- server.ListenAndServe()
}()
Expand Down
63 changes: 63 additions & 0 deletions cmd/relay/relay_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ package relay

import (
"context"
"encoding/json"
"fmt"
"net/http"
"os"
"testing"
"time"

ma "github.com/multiformats/go-multiaddr"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"

"github.com/obolnetwork/charon/app/log"
"github.com/obolnetwork/charon/p2p"
Expand Down Expand Up @@ -72,3 +78,60 @@ func TestRunBootnodeAutoP2P(t *testing.T) {
testutil.SkipIfBindErr(t, err)
require.NoError(t, err)
}

func TestServeMultiAddrs(t *testing.T) {
temp, err := os.MkdirTemp("", "")
require.NoError(t, err)

config := Config{
AutoP2PKey: true,
DataDir: temp,
LogConfig: log.DefaultConfig(),
P2PConfig: p2p.Config{TCPAddrs: []string{testutil.AvailableAddr(t).String()}},
HTTPAddr: testutil.AvailableAddr(t).String(),
}

ctx, cancel := context.WithCancel(context.Background())

var eg errgroup.Group
eg.Go(func() error {
return Run(ctx, config)
})
eg.Go(func() error {
require.Eventually(t, func() bool {
b, err := http.Get(fmt.Sprintf("http://%s", config.HTTPAddr))
if err != nil {
t.Logf("failed to get: %v", err)
return false
}
var addrs []string
err = json.NewDecoder(b.Body).Decode(&addrs)
if err != nil {
t.Logf("failed to decode: %v", err)
return false
}

if len(addrs) == 0 {
t.Logf("no addrs")
return false
}

for _, addr := range addrs {
_, err := ma.NewMultiaddr(addr)
if err != nil {
t.Logf("failed to parse multiaddr: %v [%v]", err, addr)
return false
}
}

return true
}, 2*time.Second, 100*time.Millisecond)
cancel()

return Run(ctx, config)
})

err = eg.Wait()
testutil.SkipIfBindErr(t, err)
require.NoError(t, err)
}
2 changes: 1 addition & 1 deletion dkg/dkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func setupP2P(ctx context.Context, key *ecdsa.PrivateKey, p2pConf p2p.Config, pe
return nil, nil, err
}

tcpNode, err := p2p.NewTCPNode(ctx, p2pConf, key, connGater)
tcpNode, err := p2p.NewTCPNode(ctx, p2pConf, key, connGater, p2pConf.RelayDiscovery())
if err != nil {
return nil, nil, err
}
Expand Down
7 changes: 3 additions & 4 deletions p2p/p2p.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import (
)

// NewTCPNode returns a started tcp-based libp2p host.
func NewTCPNode(ctx context.Context, cfg Config, key *ecdsa.PrivateKey, connGater ConnGater, opts ...libp2p.Option,
func NewTCPNode(ctx context.Context, cfg Config, key *ecdsa.PrivateKey, connGater ConnGater, advertise bool, opts ...libp2p.Option,
) (host.Host, error) {
addrs, err := cfg.Multiaddrs()
if err != nil {
Expand All @@ -58,7 +58,7 @@ func NewTCPNode(ctx context.Context, cfg Config, key *ecdsa.PrivateKey, connGate
}

var externalAddrs []ma.Multiaddr
if cfg.RelayDiscovery() {
if advertise {
// Use own observed addresses as soon as a single relay reports it.
// Since there are probably no other directly connected peers to do so.
identify.ActivationThresh = 1
Expand Down Expand Up @@ -87,8 +87,7 @@ func NewTCPNode(ctx context.Context, cfg Config, key *ecdsa.PrivateKey, connGate
// Enable Autonat (required for hole punching)
libp2p.EnableNATService(),
libp2p.AddrsFactory(func(addrs []ma.Multiaddr) []ma.Multiaddr {
if !cfg.RelayDiscovery() {
// Do not advertise addresses via libp2p when not using relay discovery.
if !advertise {
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion p2p/peer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestNewHost(t *testing.T) {
privKey, err := crypto.GenerateKey()
require.NoError(t, err)

_, err = p2p.NewTCPNode(context.Background(), p2p.Config{}, privKey, p2p.NewOpenGater(), nil, nil, nil)
_, err = p2p.NewTCPNode(context.Background(), p2p.Config{}, privKey, p2p.NewOpenGater(), false)
require.NoError(t, err)
}

Expand Down

0 comments on commit 1b4c97c

Please sign in to comment.