Skip to content

Commit 9594e54

Browse files
committed
feat: use circuit relay in service node
1 parent ceed9c7 commit 9594e54

File tree

8 files changed

+105
-2
lines changed

8 files changed

+105
-2
lines changed

cmd/waku/flags.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ var (
167167
Usage: "Display listening addresses according to current configuration",
168168
Destination: &options.ShowAddresses,
169169
})
170+
CircuitRelay = altsrc.NewBoolFlag(&cli.BoolFlag{
171+
Name: "circuit-relay",
172+
Usage: "Enable circuit relay service",
173+
Value: true,
174+
Destination: &options.CircuitRelay,
175+
EnvVars: []string{"WAKUNODE2_CIRCUIT_RELAY"},
176+
})
170177
LogLevel = cliutils.NewGenericFlagSingleValue(&cli.GenericFlag{
171178
Name: "log-level",
172179
Aliases: []string{"l"},

cmd/waku/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func main() {
4040
IPAddress,
4141
ExtMultiaddresses,
4242
ShowAddresses,
43+
CircuitRelay,
4344
LogLevel,
4445
LogEncoding,
4546
LogOutput,

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ require (
3535

3636
require (
3737
github.com/berty/go-libp2p-rendezvous v0.4.1
38+
github.com/cenkalti/backoff/v4 v4.1.2
3839
github.com/go-chi/chi/v5 v5.0.0
3940
github.com/lib/pq v1.10.4
4041
github.com/waku-org/go-noise v0.0.4

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0Bsq
247247
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
248248
github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
249249
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
250+
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
250251
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
251252
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
252253
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=

waku/node.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ func Execute(options Options) {
133133
libp2pOpts = append(libp2pOpts, libp2p.NATPortMap()) // Attempt to open ports using uPNP for NATed hosts.)
134134
}
135135

136+
// Node can be a circuit relay server
137+
if options.CircuitRelay {
138+
libp2pOpts = append(libp2pOpts, libp2p.EnableRelayService())
139+
}
140+
136141
if options.UserAgent != "" {
137142
libp2pOpts = append(libp2pOpts, libp2p.UserAgent(options.UserAgent))
138143
}

waku/options.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ type Options struct {
155155
KeepAlive time.Duration
156156
AdvertiseAddresses []multiaddr.Multiaddr
157157
ShowAddresses bool
158+
CircuitRelay bool
158159
LogLevel string
159160
LogEncoding string
160161
LogOutput string

waku/v2/node/wakunode2.go

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"sync"
1010
"time"
1111

12+
backoffv4 "github.com/cenkalti/backoff/v4"
1213
golog "github.com/ipfs/go-log/v2"
1314
"github.com/libp2p/go-libp2p"
1415
"go.uber.org/zap"
@@ -23,6 +24,8 @@ import (
2324
"github.com/libp2p/go-libp2p/core/peerstore"
2425
"github.com/libp2p/go-libp2p/core/protocol"
2526
"github.com/libp2p/go-libp2p/p2p/discovery/backoff"
27+
"github.com/libp2p/go-libp2p/p2p/host/autorelay"
28+
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto"
2629
ws "github.com/libp2p/go-libp2p/p2p/transport/websocket"
2730
ma "github.com/multiformats/go-multiaddr"
2831
"go.opencensus.io/stats"
@@ -89,7 +92,8 @@ type WakuNode struct {
8992
store ReceptorService
9093
rlnRelay RLNRelay
9194

92-
wakuFlag enr.WakuEnrBitfield
95+
wakuFlag enr.WakuEnrBitfield
96+
circuitRelayNodes chan peer.AddrInfo
9397

9498
localNode *enode.LocalNode
9599

@@ -177,6 +181,34 @@ func New(opts ...WakuNodeOption) (*WakuNode, error) {
177181
w.wg = &sync.WaitGroup{}
178182
w.keepAliveFails = make(map[peer.ID]int)
179183
w.wakuFlag = enr.NewWakuEnrBitfield(w.opts.enableLightPush, w.opts.enableLegacyFilter, w.opts.enableStore, w.opts.enableRelay)
184+
w.circuitRelayNodes = make(chan peer.AddrInfo)
185+
186+
// Use circuit relay with nodes received on circuitRelayNodes channel
187+
params.libP2POpts = append(params.libP2POpts, libp2p.EnableAutoRelayWithPeerSource(
188+
func(ctx context.Context, numPeers int) <-chan peer.AddrInfo {
189+
r := make(chan peer.AddrInfo)
190+
go func() {
191+
defer close(r)
192+
for ; numPeers != 0; numPeers-- {
193+
select {
194+
case v, ok := <-w.circuitRelayNodes:
195+
if !ok {
196+
return
197+
}
198+
select {
199+
case r <- v:
200+
case <-ctx.Done():
201+
return
202+
}
203+
case <-ctx.Done():
204+
return
205+
}
206+
}
207+
}()
208+
return r
209+
},
210+
autorelay.WithMinInterval(0),
211+
))
180212

181213
if params.enableNTP {
182214
w.timesource = timesource.NewNTPTimesource(w.opts.ntpURLs, w.log)
@@ -305,10 +337,11 @@ func (w *WakuNode) Start(ctx context.Context) error {
305337

306338
w.enrChangeCh = make(chan struct{}, 10)
307339

308-
w.wg.Add(3)
340+
w.wg.Add(4)
309341
go w.connectednessListener(ctx)
310342
go w.watchMultiaddressChanges(ctx)
311343
go w.watchENRChanges(ctx)
344+
go w.findRelayNodes(ctx)
312345

313346
err = w.bcaster.Start(ctx)
314347
if err != nil {
@@ -812,3 +845,56 @@ func (w *WakuNode) Peers() ([]*Peer, error) {
812845
}
813846
return peers, nil
814847
}
848+
849+
func (w *WakuNode) findRelayNodes(ctx context.Context) {
850+
defer w.wg.Done()
851+
852+
// Feed peers more often right after the bootstrap, then backoff
853+
bo := backoffv4.NewExponentialBackOff()
854+
bo.InitialInterval = 15 * time.Second
855+
bo.Multiplier = 3
856+
bo.MaxInterval = 1 * time.Hour
857+
bo.MaxElapsedTime = 0 // never stop
858+
t := backoffv4.NewTicker(bo)
859+
defer t.Stop()
860+
for {
861+
select {
862+
case <-t.C:
863+
case <-ctx.Done():
864+
return
865+
}
866+
867+
peers, err := w.Peers()
868+
if err != nil {
869+
w.log.Error("failed to fetch peers", zap.Error(err))
870+
continue
871+
}
872+
873+
// Shuffle peers
874+
rand.Seed(time.Now().UnixNano())
875+
rand.Shuffle(len(peers), func(i, j int) { peers[i], peers[j] = peers[j], peers[i] })
876+
877+
for _, p := range peers {
878+
info := w.Host().Peerstore().PeerInfo(p.ID)
879+
880+
supportedProtocols, err := w.Host().Peerstore().SupportsProtocols(p.ID, proto.ProtoIDv2Hop)
881+
if err != nil {
882+
w.log.Error("could not check supported protocols", zap.Error(err))
883+
continue
884+
}
885+
886+
if len(supportedProtocols) == 0 {
887+
continue
888+
}
889+
890+
select {
891+
case <-ctx.Done():
892+
w.log.Debug("context done, auto-relay has enough peers")
893+
return
894+
895+
case w.circuitRelayNodes <- info:
896+
w.log.Debug("published auto-relay peer info", zap.Any("peer-id", p.ID))
897+
}
898+
}
899+
}
900+
}

waku/v2/node/wakuoptions.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ var DefaultLibP2POptions = []libp2p.Option{
524524
),
525525
libp2p.EnableNATService(),
526526
libp2p.ConnectionManager(newConnManager(200, 300, connmgr.WithGracePeriod(0))),
527+
libp2p.EnableHolePunching(),
527528
}
528529

529530
func newConnManager(lo int, hi int, opts ...connmgr.Option) *connmgr.BasicConnMgr {

0 commit comments

Comments
 (0)