From a37beea54277da4df9105b5b5b93830749b2ec49 Mon Sep 17 00:00:00 2001 From: Dmitry Holodov Date: Thu, 16 Mar 2023 14:39:51 -0500 Subject: [PATCH] advertisement callback now returns the list of provided namespaces (#4) * changed advertisement callback to return the provided namespaces * added linting support * can't refresh namespaces before discovery loop is started * fixed log message * removed incorrect comment * RefreshNamespaces renamed Advertise --- .golangci.yml | 116 ++++++++++++++++++++++++++++++++++++++++ Makefile | 32 +++++++++++ discovery.go | 100 +++++++++++++++------------------- discovery_test.go | 14 +++-- go.mod | 27 +++++----- go.sum | 52 +++++++++--------- host.go | 30 +++++------ host_test.go | 12 +++-- scripts/install-lint.sh | 11 ++++ utils.go | 4 +- 10 files changed, 269 insertions(+), 129 deletions(-) create mode 100644 .golangci.yml create mode 100644 Makefile create mode 100755 scripts/install-lint.sh diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..4a3ba66 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,116 @@ +run: + # timeout for analysis, e.g. 30s, 5m, default is 1m + deadline: 5m + + # list of build tags, all linters use it. Default is empty list. + build-tags: + - integration + +# all available settings of specific linters +linters-settings: + govet: + # report about shadowed variables + check-shadowing: true + enable-all: true + disable: + - fieldalignment + + goimports: + local-prefixes: github.com/athanorlabs/atomic-swap + + maligned: + # print struct with more effective memory layout or not, false by default + suggest-new: true + + dupl: + # tokens count to trigger issue, 150 by default + threshold: 100 + + misspell: + # Correct spellings using locale preferences for US or UK. + # Default is to use a neutral variety of English. + # Setting locale to US will correct the British spelling of 'colour' to 'color'. + + tagliatelle: + # Check the struct tag name case. + case: + rules: + # See https://github.com/ldez/tagliatelle for values and examples: + json: goCamel + + gocritic: + # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint` run to see all tags and checks. + # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". + enabled-tags: + - performance + settings: # settings passed to gocritic + captLocal: # must be valid enabled check name + paramsOnly: true + rangeValCopy: + sizeThreshold: 32 + +linters: + enable: + - bidichk + - bodyclose + - depguard + - errcheck + - exportloopref + - goconst + - gocyclo + - gofmt + - goimports + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - lll + - megacheck + - misspell + - nolintlint + - predeclared + - revive + - staticcheck + - tagliatelle + - typecheck + - unconvert + - unparam + - unused + - usestdlibvars + + fast: false + +issues: + # List of regexps of issue texts to exclude, empty list by default. + # But independently from this option we use default exclude patterns, + # it can be disabled by `exclude-use-default: false`. To list all + # excluded by default patterns execute `golangci-lint run --help` + #exclude: + + # Excluding configuration per-path, per-linter, per-text and per-source + exclude-rules: + # Exclude some linters from running on tests files. + - path: _test\.go + linters: + - gocyclo + - errcheck + - dupl + - gosec + - ineffassign + + - text: 'G204: Subprocess launched with variable' + linters: + - gosec + + # Independently from option `exclude` we use default exclude patterns, + # it can be disabled by this option. To list all + # excluded by default patterns execute `golangci-lint run --help`. + # Default value for this option is true. + exclude-use-default: false + + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. + max-per-linter: 0 + + # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. + max-same-issues: 0 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8c55cea --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +GOPATH ?= $(shell go env GOPATH) + +.PHONY: all +all: format lint test + +.PHONY: lint-go +lint-go: + ./scripts/install-lint.sh + ${GOPATH}/bin/golangci-lint run + +.PHONY: lint-shell +lint-shell: + shellcheck --source-path=.:scripts scripts/*.sh + +.PHONY: lint +lint: lint-go lint-shell + +.PHONY: format-go +format-go: + test -x $(GOPATH)/bin/goimports || go install golang.org/x/tools/cmd/goimports@latest + $(GOPATH)/bin/goimports -local github.com/athanorlabs/go-p2p-net -w . + +.PHONY: format-shell +format-shell: + shfmt -w scripts/*.sh + +.PHONY: format +format: format-go format-shell + +.PHONY: test +test: + go test ./... -v -timeout=5m -count=1 diff --git a/discovery.go b/discovery.go index 32a422c..a91d46c 100644 --- a/discovery.go +++ b/discovery.go @@ -21,22 +21,28 @@ const ( defaultMaxPeers = 50 // TODO: make this configurable ) -// ShouldAdvertiseFunc is the type for a function that returns whether we should -// regularly advertise inside the advertisement loop. -// If it returns false, we don't advertise until the next loop iteration. -type ShouldAdvertiseFunc = func() bool - type discovery struct { - ctx context.Context - dht *dual.DHT - h libp2phost.Host - rd *libp2prouting.RoutingDiscovery - advertiseCh chan []string // signals to advertise - shouldAdvertiseFunc ShouldAdvertiseFunc + ctx context.Context + dht *dual.DHT + h libp2phost.Host + rd *libp2prouting.RoutingDiscovery + advertiseCh chan struct{} // signals to advertise + advertisedNamespaces func() []string +} + +// setAdvertisedNamespacesFunc sets the function used to query the list of +// namespaces to be advertised on every cycle of the advertisement loop. In most +// use cases, this function should always return the empty namespace ("") on top +// of any additional namespaces that should be advertised. +func (d *discovery) setAdvertisedNamespacesFunc(fn func() []string) { + d.advertisedNamespaces = fn } -func (d *discovery) setShouldAdvertiseFunc(fn ShouldAdvertiseFunc) { - d.shouldAdvertiseFunc = fn +func (d *discovery) getAdvertisedNamespaces() []string { + if d.advertisedNamespaces == nil { + return []string{""} + } + return d.advertisedNamespaces() } func (d *discovery) start() error { @@ -59,61 +65,41 @@ func (d *discovery) stop() error { } func (d *discovery) advertiseLoop() { - var toAdvertise []string - ttl := d.advertise(toAdvertise) + ttl := time.Duration(0) // don't block on first loop iteration for { select { - case ta := <-d.advertiseCh: - toAdvertise = ta - ttl = d.advertise(toAdvertise) - case <-time.After(ttl): - // the DHT clears provider records (ie. who is advertising what content) - // every 24 hours. - // so, if we don't have any offers available for 24 hours, then we are - // no longer present in the DHT as a provider. - // otherwise, we'll be present, but no offers will be sent when peers - // query us. - // - // this function is set in net/swapnet/host.go SetHandler(). - if d.shouldAdvertiseFunc != nil && !d.shouldAdvertiseFunc() { - continue - } - - ttl = d.advertise(toAdvertise) case <-d.ctx.Done(): return + case <-d.advertiseCh: + // we've been asked to publish advertisements immediately, presumably + // because a new namespace was added + case <-time.After(ttl): + // publish advertisements on regular interval } + + // The DHT clears provider records (ie. who is advertising what content) + // every 24 hours. So, if we don't advertise a namespace for 24 hours, + // then we are no longer present in the DHT under that namespace. + ttl = d.advertise(d.getAdvertisedNamespaces()) } } -// advertise advertises that we provide XMR in the DHT. -// note: we only advertise that we are an XMR provider, but we don't -// advertise our specific offers. -// to find what our offers are, peers need to send us a QueryRequest -// over the query subprotocol. -// the return value is the amount of time the caller should wait before -// trying to advertise again. -func (d *discovery) advertise(toAdvertise []string) time.Duration { - log.Debug("advertising in the DHT...") +// advertise advertises the passed set of namespaces in the DHT. +func (d *discovery) advertise(namespaces []string) time.Duration { err := d.dht.Bootstrap(d.ctx) if err != nil { - log.Warnf("failed to bootstrap DHT: err=%s", err) - return tryAdvertiseTimeout - } - - _, err = d.rd.Advertise(d.ctx, "") - if err != nil { - log.Debugf("failed to advertise in the DHT: err=%s", err) + log.Warnf("failed to bootstrap DHT: %s", err) return tryAdvertiseTimeout } - for _, provides := range toAdvertise { + for _, provides := range namespaces { _, err = d.rd.Advertise(d.ctx, provides) if err != nil { - log.Debugf("failed to advertise in the DHT: err=%s", err) + log.Debugf("failed to advertise %q in the DHT: %s", provides, err) return tryAdvertiseTimeout } + log.Debugf("advertised %q in the DHT", provides) } return defaultAdvertiseTTL @@ -165,26 +151,26 @@ func (d *discovery) findPeers(provides string, timeout time.Duration) ([]peer.ID return peerIDs, nil } return peerIDs, ctx.Err() - case peer, ok := <-peerCh: + case peerAddr, ok := <-peerCh: if !ok { // channel was closed, no more peers to read return peerIDs, nil } - if peer.ID == ourPeerID { + if peerAddr.ID == ourPeerID { continue } - log.Debugf("found new peer via DHT: %s", peer) - peerIDs = append(peerIDs, peer.ID) + log.Debugf("found new peer via DHT: %s", peerAddr) + peerIDs = append(peerIDs, peerAddr.ID) // found a peer, try to connect if we need more peers if len(d.h.Network().Peers()) < defaultMaxPeers { - err = d.h.Connect(d.ctx, peer) + err = d.h.Connect(d.ctx, peerAddr) if err != nil { - log.Debugf("failed to connect to discovered peer %s: %s", peer.ID, err) + log.Debugf("failed to connect to discovered peer %s: %s", peerAddr.ID, err) } } else { - d.h.Peerstore().AddAddrs(peer.ID, peer.Addrs, peerstore.PermanentAddrTTL) + d.h.Peerstore().AddAddrs(peerAddr.ID, peerAddr.Addrs, peerstore.PermanentAddrTTL) } } } diff --git a/discovery_test.go b/discovery_test.go index bda3aa0..55a048b 100644 --- a/discovery_test.go +++ b/discovery_test.go @@ -13,9 +13,11 @@ func TestHost_Discover(t *testing.T) { ha := newHost(t, basicTestConfig(t)) err := ha.Start() require.NoError(t, err) + hb := newHost(t, basicTestConfig(t)) err = hb.Start() require.NoError(t, err) + hc := newHost(t, basicTestConfig(t)) err = hc.Start() require.NoError(t, err) @@ -31,13 +33,15 @@ func TestHost_Discover(t *testing.T) { require.GreaterOrEqual(t, len(hb.h.Network().Peers()), 2) require.GreaterOrEqual(t, len(hc.h.Network().Peers()), 1) - strs := []string{"test"} - ha.Advertise(strs) - hb.Advertise(strs) - hc.Advertise(strs) + providedNamesapces := func() []string { + return []string{"test"} + } + ha.SetAdvertisedNamespacesFunc(providedNamesapces) + hb.SetAdvertisedNamespacesFunc(providedNamesapces) + hc.SetAdvertisedNamespacesFunc(providedNamesapces) time.Sleep(testAdvertisementSleepDuration) - peerIDs, err := hc.Discover(strs[0], time.Second) + peerIDs, err := hc.Discover("test", time.Second) require.NoError(t, err) require.GreaterOrEqual(t, len(peerIDs), 1) require.NotEmpty(t, peerIDs[0]) diff --git a/go.mod b/go.mod index 8b83c34..cc72cd5 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/ipfs/go-ds-badger2 v0.1.3 github.com/ipfs/go-log v1.0.5 - github.com/libp2p/go-libp2p v0.26.0 + github.com/libp2p/go-libp2p v0.26.2 github.com/libp2p/go-libp2p-kad-dht v0.21.1 github.com/multiformats/go-multiaddr v0.8.0 github.com/stretchr/testify v1.8.1 @@ -32,12 +32,12 @@ require ( github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.0.0 // indirect + github.com/golang/glog v1.1.0 // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230222194610-99052d3372e7 // indirect + github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10 // indirect github.com/google/uuid v1.3.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -53,7 +53,6 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.16.0 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/koron/go-ssdp v0.0.4 // indirect @@ -76,8 +75,6 @@ require ( github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect @@ -88,7 +85,7 @@ require ( github.com/multiformats/go-multihash v0.2.1 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.8.3 // indirect + github.com/onsi/ginkgo/v2 v2.9.0 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -97,7 +94,7 @@ require ( github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.40.0 // indirect + github.com/prometheus/common v0.41.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.2.1 // indirect @@ -113,14 +110,14 @@ require ( go.uber.org/fx v1.19.2 // indirect go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.6.0 // indirect - golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/exp v0.0.0-20230307190834-24139beb5833 // indirect + golang.org/x/mod v0.9.0 // indirect + golang.org/x/net v0.8.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.6.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + golang.org/x/tools v0.7.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.1.7 // indirect diff --git a/go.sum b/go.sum index 53f8de9..06ac173 100644 --- a/go.sum +++ b/go.sum @@ -115,8 +115,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= @@ -161,8 +161,8 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20230222194610-99052d3372e7 h1:pNFnpaSXfibgW7aUbk9pwLmI7LNwh/iR46x/YwN/lNg= -github.com/google/pprof v0.0.0-20230222194610-99052d3372e7/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= +github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10 h1:CqYfpuYIjnlNxM3msdyPRKabhXZWbKjf3Q8BWROFBso= +github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -226,7 +226,6 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -260,8 +259,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.26.0 h1:0FE0bP9/G9YADjruqoFvf1snBBFvrdh1MmTuEeUkl2E= -github.com/libp2p/go-libp2p v0.26.0/go.mod h1:R8N+XhwPDPLNb4TKboKJKnDeg9vPw8+zlC6g793dTGw= +github.com/libp2p/go-libp2p v0.26.2 h1:eHEoW/696FP7/6DxOvcrKfTD6Bi0DExxiMSZUJxswA0= +github.com/libp2p/go-libp2p v0.26.2/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-kad-dht v0.21.1 h1:xpfp8/t9+X2ip1l8Umap1/UGNnJ3RHJgKGAEsnRAlTo= @@ -319,7 +318,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -352,9 +350,9 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/onsi/ginkgo/v2 v2.8.3 h1:RpbK1G8nWPNaCVFBWsOGnEQQGgASi6b8fxcWBvDYjxQ= -github.com/onsi/ginkgo/v2 v2.8.3/go.mod h1:6OaUA8BCi0aZfmzYT/q9AacwTzDpNbxILUT+TlBq6MY= -github.com/onsi/gomega v1.27.0 h1:QLidEla4bXUuZVFa4KX6JHCsuGgbi85LC/pCHrt/O08= +github.com/onsi/ginkgo/v2 v2.9.0 h1:Tugw2BKlNHTMfG+CheOITkYvk4LAh6MFOvikhGVnhE8= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/gomega v1.27.1 h1:rfztXRbg6nv/5f+Raen9RcGoSecHIFgBBLQK3Wdj754= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -378,8 +376,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.40.0 h1:Afz7EVRqGg2Mqqf4JuF9vdvp1pi220m55Pi9T2JnO4Q= -github.com/prometheus/common v0.40.0/go.mod h1:L65ZJPSmfn/UBWLQIHV7dBrKFidB/wPlF1y5TlSt9OE= +github.com/prometheus/common v0.41.0 h1:npo01n6vUlRViIj5fgwiK8vlNIh8bnoxqh3gypKsyAw= +github.com/prometheus/common v0.41.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= @@ -506,11 +504,11 @@ golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230307190834-24139beb5833 h1:SChBja7BCQewoTAU7IgvucQKMIXrEpFxNMs0spT3/5s= +golang.org/x/exp v0.0.0-20230307190834-24139beb5833/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -524,8 +522,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -546,8 +544,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -593,8 +591,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -604,8 +602,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -629,8 +627,8 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/host.go b/host.go index 48a3fa9..a10b429 100644 --- a/host.go +++ b/host.go @@ -22,7 +22,6 @@ import ( "github.com/libp2p/go-libp2p/core/peerstore" "github.com/libp2p/go-libp2p/core/protocol" libp2pdiscovery "github.com/libp2p/go-libp2p/p2p/discovery/routing" - "github.com/libp2p/go-libp2p/p2p/host/autorelay" "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds" routedhost "github.com/libp2p/go-libp2p/p2p/host/routed" ma "github.com/multiformats/go-multiaddr" @@ -113,7 +112,7 @@ func NewHost(cfg *Config) (*Host, error) { } if len(bns) > 0 { - opts = append(opts, libp2p.EnableAutoRelay(autorelay.WithStaticRelays(bns))) + opts = append(opts, libp2p.EnableAutoRelayWithStaticRelays(bns)) } // create libp2p host instance @@ -157,7 +156,7 @@ func NewHost(cfg *Config) (*Host, error) { dht: dht, h: routedHost, rd: libp2pdiscovery.NewRoutingDiscovery(dht), - advertiseCh: make(chan []string), + advertiseCh: make(chan struct{}), }, } @@ -170,8 +169,6 @@ func (h *Host) Start() error { log.Info("started listening: address=", addr) } - // ignore error - node should still be able to run without connecting to - // bootstrap nodes (for now) if err := h.bootstrap(); err != nil { return err } @@ -222,17 +219,13 @@ func (h *Host) Stop() error { } // Advertise advertises in the DHT. -func (h *Host) Advertise(strs []string) { - h.discovery.advertiseCh <- strs +func (h *Host) Advertise() { + h.discovery.advertiseCh <- struct{}{} } // Addresses returns the list of multiaddress the host is listening on. -func (h *Host) Addresses() []string { - var addrs []string - for _, ma := range h.multiaddrs() { - addrs = append(addrs, ma.String()) - } - return addrs +func (h *Host) Addresses() []ma.Multiaddr { + return h.multiaddrs() } // PeerID returns the host's peer ID. @@ -271,10 +264,11 @@ func (h *Host) SetStreamHandler(pid string, handler func(libp2pnetwork.Stream)) log.Debugf("supporting protocol %s", protocol.ID(h.protocolID+pid)) } -// SetShouldAdvertiseFunc sets the function which is called before auto-advertising in -// the DHT. If it returns false, we don't advertise automatically. -func (h *Host) SetShouldAdvertiseFunc(fn ShouldAdvertiseFunc) { - h.discovery.setShouldAdvertiseFunc(fn) +// SetAdvertisedNamespacesFunc sets the function that is called to determine +// which namespaces should be advertised in the DHT. In most use cases, the +// passed function should, at minimum, return the empty ("") namespace. +func (h *Host) SetAdvertisedNamespacesFunc(fn func() []string) { + h.discovery.setAdvertisedNamespacesFunc(fn) } // Connectedness returns the connectedness state of a given peer. @@ -315,7 +309,7 @@ func (h *Host) bootstrap() error { selfID := h.PeerID() - var failed uint64 = 0 + failed := uint64(0) var wg sync.WaitGroup for _, bn := range h.bootnodes { if bn.ID == selfID { diff --git a/host_test.go b/host_test.go index 6160fe2..6cce2f8 100644 --- a/host_test.go +++ b/host_test.go @@ -61,21 +61,23 @@ func TestAdvertiseDiscover(t *testing.T) { require.NotEmpty(t, h1Addresses) cfgH2 := basicTestConfig(t) - cfgH2.Bootnodes = []string{h1Addresses[0]} + cfgH2.Bootnodes = []string{h1Addresses[0].String()} h2 := newHost(t, cfgH2) err = h2.Start() require.NoError(t, err) - nameSpaces := []string{"one", "two", "three"} - h1.Advertise(nameSpaces) + nameSpaces := []string{"", "one", "two", "three"} + advertisedNamespaces := func() []string { + return nameSpaces + } + h1.SetAdvertisedNamespacesFunc(advertisedNamespaces) // Advertise only puts the namespaces to advertise into a channel. It // doesn't block until the advertisements are actually sent. time.Sleep(500 * time.Millisecond) - allNamespaces := append(nameSpaces, "") - for _, ns := range allNamespaces { + for _, ns := range nameSpaces { peerIDs, err := h2.Discover(ns, time.Second*3) require.NoError(t, err) require.Len(t, peerIDs, 1) diff --git a/scripts/install-lint.sh b/scripts/install-lint.sh new file mode 100755 index 0000000..7251ff0 --- /dev/null +++ b/scripts/install-lint.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# Installs golangci-lint (https://golangci-lint.run) into the user's personal GOPATH bin directory if it is +# not there already or if the version does not match the value defined below. + +VERSION="v1.50.1" +GOBIN="$(go env GOPATH)/bin" +LINT="${GOBIN}/golangci-lint" + +if [[ ! -x "${LINT}" ]] || [[ "v$("${LINT}" version --format=short)" != "${VERSION}" ]]; then + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "${GOBIN}" "${VERSION}" +fi diff --git a/utils.go b/utils.go index 7c88c13..7e283fc 100644 --- a/utils.go +++ b/utils.go @@ -38,7 +38,7 @@ func WriteStreamMessage(s io.Writer, msg Message, peerID peer.ID) error { return err } - log.Debugf("Sent message to peer=%s type=%s", peerID, msg.Type()) + log.Debugf("Sent message to peer=%s type=%d", peerID, msg.Type()) return nil } @@ -133,7 +133,7 @@ func generateKey(seed int64, fp string) (crypto.PrivKey, error) { if seed == 0 { r = crand.Reader } else { - r = mrand.New(mrand.NewSource(seed)) //nolint + r = mrand.New(mrand.NewSource(seed)) } key, _, err := crypto.GenerateEd25519Key(r) if err != nil {