Commit 12ca1b88 authored by Janoš Guljaš's avatar Janoš Guljaš Committed by GitHub

add p2p stream headers and tracing (#27)

parent 3132c693
...@@ -27,18 +27,21 @@ import ( ...@@ -27,18 +27,21 @@ import (
func (c *command) initStartCmd() (err error) { func (c *command) initStartCmd() (err error) {
const ( const (
optionNameDataDir = "data-dir" optionNameDataDir = "data-dir"
optionNamePassword = "password" optionNamePassword = "password"
optionNamePasswordFile = "password-file" optionNamePasswordFile = "password-file"
optionNameAPIAddr = "api-addr" optionNameAPIAddr = "api-addr"
optionNameP2PAddr = "p2p-addr" optionNameP2PAddr = "p2p-addr"
optionNameP2PDisableWS = "p2p-disable-ws" optionNameP2PDisableWS = "p2p-disable-ws"
optionNameP2PDisableQUIC = "p2p-disable-quic" optionNameP2PDisableQUIC = "p2p-disable-quic"
optionNameEnableDebugAPI = "enable-debug-api" optionNameEnableDebugAPI = "enable-debug-api"
optionNameDebugAPIAddr = "debug-api-addr" optionNameDebugAPIAddr = "debug-api-addr"
optionNameBootnodes = "bootnode" optionNameBootnodes = "bootnode"
optionNameNetworkID = "network-id" optionNameNetworkID = "network-id"
optionNameVerbosity = "verbosity" optionNameTracingEnabled = "tracing"
optionNameTracingEndpoint = "tracing-endpoint"
optionNameTracingServiceName = "tracing-service-name"
optionNameVerbosity = "verbosity"
) )
cmd := &cobra.Command{ cmd := &cobra.Command{
...@@ -101,8 +104,11 @@ func (c *command) initStartCmd() (err error) { ...@@ -101,8 +104,11 @@ func (c *command) initStartCmd() (err error) {
NetworkID: c.config.GetInt32(optionNameNetworkID), NetworkID: c.config.GetInt32(optionNameNetworkID),
Logger: logger, Logger: logger,
}, },
Bootnodes: c.config.GetStringSlice(optionNameBootnodes), Bootnodes: c.config.GetStringSlice(optionNameBootnodes),
Logger: logger, TracingEnabled: c.config.GetBool(optionNameTracingEnabled),
TracingEndpoint: c.config.GetString(optionNameTracingEndpoint),
TracingServiceName: c.config.GetString(optionNameTracingServiceName),
Logger: logger,
}) })
if err != nil { if err != nil {
return err return err
...@@ -158,6 +164,9 @@ func (c *command) initStartCmd() (err error) { ...@@ -158,6 +164,9 @@ func (c *command) initStartCmd() (err error) {
cmd.Flags().Bool(optionNameEnableDebugAPI, false, "enable debug HTTP API") cmd.Flags().Bool(optionNameEnableDebugAPI, false, "enable debug HTTP API")
cmd.Flags().String(optionNameDebugAPIAddr, ":6060", "debug HTTP API listen address") cmd.Flags().String(optionNameDebugAPIAddr, ":6060", "debug HTTP API listen address")
cmd.Flags().Int32(optionNameNetworkID, 1, "ID of the Swarm network") cmd.Flags().Int32(optionNameNetworkID, 1, "ID of the Swarm network")
cmd.Flags().Bool(optionNameTracingEnabled, false, "enable tracing")
cmd.Flags().String(optionNameTracingEndpoint, "127.0.0.1:6831", "endpoint to send tracing data")
cmd.Flags().String(optionNameTracingServiceName, "bee", "service name identifier for tracing")
cmd.Flags().String(optionNameVerbosity, "info", "log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace") cmd.Flags().String(optionNameVerbosity, "info", "log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace")
c.root.AddCommand(cmd) c.root.AddCommand(cmd)
......
...@@ -17,10 +17,13 @@ require ( ...@@ -17,10 +17,13 @@ require (
github.com/libp2p/go-ws-transport v0.2.0 github.com/libp2p/go-ws-transport v0.2.0
github.com/multiformats/go-multiaddr v0.2.0 github.com/multiformats/go-multiaddr v0.2.0
github.com/multiformats/go-multistream v0.1.0 github.com/multiformats/go-multistream v0.1.0
github.com/opentracing/opentracing-go v1.0.2
github.com/prometheus/client_golang v1.3.0 github.com/prometheus/client_golang v1.3.0
github.com/sirupsen/logrus v1.4.2 github.com/sirupsen/logrus v1.4.2
github.com/spf13/cobra v0.0.5 github.com/spf13/cobra v0.0.5
github.com/spf13/viper v1.6.2 github.com/spf13/viper v1.6.2
github.com/uber/jaeger-client-go v2.22.1+incompatible
github.com/uber/jaeger-lib v2.2.0+incompatible // indirect
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915 golang.org/x/crypto v0.0.0-20191219195013-becbf705a915
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
resenje.org/web v0.4.0 resenje.org/web v0.4.0
......
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75 h1:3ILjVyslFbc4jl1w5TWuvvslFD/nDfR2H8tVaMVLrEY=
github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod h1:uAXEEpARkRhCZfEvy/y0Jcc888f9tHCc1W7/UeEtreE= github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod h1:uAXEEpARkRhCZfEvy/y0Jcc888f9tHCc1W7/UeEtreE=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
...@@ -50,7 +48,6 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc ...@@ -50,7 +48,6 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ=
github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
...@@ -78,11 +75,9 @@ github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= ...@@ -78,11 +75,9 @@ github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
...@@ -93,12 +88,10 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l ...@@ -93,12 +88,10 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
...@@ -117,12 +110,10 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+ ...@@ -117,12 +110,10 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo=
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
...@@ -132,7 +123,6 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj ...@@ -132,7 +123,6 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj
github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw=
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8=
github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s=
...@@ -149,7 +139,6 @@ github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQ ...@@ -149,7 +139,6 @@ github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQ
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc=
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A=
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs=
...@@ -162,7 +151,6 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 ...@@ -162,7 +151,6 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
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= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0=
...@@ -171,16 +159,13 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW ...@@ -171,16 +159,13 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d h1:68u9r4wEvL3gYg2jvAOgROwZ3H+Y3hIDk4tbbmIjcYQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d h1:68u9r4wEvL3gYg2jvAOgROwZ3H+Y3hIDk4tbbmIjcYQ=
github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88=
github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ=
...@@ -204,7 +189,6 @@ github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/ ...@@ -204,7 +189,6 @@ github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/
github.com/libp2p/go-libp2p-autonat-svc v0.1.0 h1:28IM7iWMDclZeVkpiFQaWVANwXwE7zLlpbnS7yXxrfs= github.com/libp2p/go-libp2p-autonat-svc v0.1.0 h1:28IM7iWMDclZeVkpiFQaWVANwXwE7zLlpbnS7yXxrfs=
github.com/libp2p/go-libp2p-autonat-svc v0.1.0/go.mod h1:fqi8Obl/z3R4PFVLm8xFtZ6PBL9MlV/xumymRFkKq5A= github.com/libp2p/go-libp2p-autonat-svc v0.1.0/go.mod h1:fqi8Obl/z3R4PFVLm8xFtZ6PBL9MlV/xumymRFkKq5A=
github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro=
github.com/libp2p/go-libp2p-blankhost v0.1.4 h1:I96SWjR4rK9irDHcHq3XHN6hawCRTPUADzkJacgZLvk=
github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU=
github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8=
github.com/libp2p/go-libp2p-circuit v0.1.4 h1:Phzbmrg3BkVzbqd4ZZ149JxCuUWu2wZcXf/Kr6hZJj8= github.com/libp2p/go-libp2p-circuit v0.1.4 h1:Phzbmrg3BkVzbqd4ZZ149JxCuUWu2wZcXf/Kr6hZJj8=
...@@ -248,12 +232,9 @@ github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MB ...@@ -248,12 +232,9 @@ github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MB
github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0=
github.com/libp2p/go-libp2p-testing v0.1.1 h1:U03z3HnGI7Ni8Xx6ONVZvUFOAzWYmolWf5W5jAOPNmU=
github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0=
github.com/libp2p/go-libp2p-tls v0.1.1 h1:tjW7njTM8JX8FbEvqr8/VSKBdZYZ7CtGtv3i6NiFf10= github.com/libp2p/go-libp2p-tls v0.1.1 h1:tjW7njTM8JX8FbEvqr8/VSKBdZYZ7CtGtv3i6NiFf10=
github.com/libp2p/go-libp2p-tls v0.1.1/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= github.com/libp2p/go-libp2p-tls v0.1.1/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M=
github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM=
github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M=
github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw=
github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA=
github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8=
...@@ -273,7 +254,6 @@ github.com/libp2p/go-nat v0.0.4 h1:KbizNnq8YIf7+Hn7+VFL/xE0eDrkPru2zIO9NMwL8UQ= ...@@ -273,7 +254,6 @@ github.com/libp2p/go-nat v0.0.4 h1:KbizNnq8YIf7+Hn7+VFL/xE0eDrkPru2zIO9NMwL8UQ=
github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo=
github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0=
github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
github.com/libp2p/go-openssl v0.0.4 h1:d27YZvLoTyMhIN4njrkr8zMDOM4lfpHIp6A+TK9fovg=
github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw=
github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
...@@ -371,11 +351,9 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn ...@@ -371,11 +351,9 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
...@@ -384,7 +362,6 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 ...@@ -384,7 +362,6 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
...@@ -414,14 +391,11 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR ...@@ -414,14 +391,11 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
...@@ -444,7 +418,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ ...@@ -444,7 +418,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
...@@ -455,6 +428,11 @@ github.com/tdewolff/parse/v2 v2.4.1/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1I ...@@ -455,6 +428,11 @@ github.com/tdewolff/parse/v2 v2.4.1/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1I
github.com/tdewolff/test v1.0.4/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tdewolff/test v1.0.4/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/uber/jaeger-client-go v2.22.1+incompatible h1:NHcubEkVbahf9t3p75TOCR83gdUHXjRJvjoBh1yACsM=
github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v1.5.0 h1:OHbgr8l656Ub3Fw5k9SWnBfIEwvoHQ+W2y+Aa9D1Uyo=
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM= github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM=
...@@ -480,6 +458,7 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= ...@@ -480,6 +458,7 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs= go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
...@@ -561,7 +540,6 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3 ...@@ -561,7 +540,6 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
...@@ -580,9 +558,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks ...@@ -580,9 +558,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
...@@ -591,7 +567,6 @@ gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= ...@@ -591,7 +567,6 @@ gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
......
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"github.com/ethersphere/bee/pkg/logging" "github.com/ethersphere/bee/pkg/logging"
m "github.com/ethersphere/bee/pkg/metrics" m "github.com/ethersphere/bee/pkg/metrics"
"github.com/ethersphere/bee/pkg/pingpong" "github.com/ethersphere/bee/pkg/pingpong"
"github.com/ethersphere/bee/pkg/tracing"
) )
type Service interface { type Service interface {
...@@ -26,6 +27,7 @@ type server struct { ...@@ -26,6 +27,7 @@ type server struct {
type Options struct { type Options struct {
Pingpong pingpong.Interface Pingpong pingpong.Interface
Logger logging.Logger Logger logging.Logger
Tracer *tracing.Tracer
} }
func New(o Options) Service { func New(o Options) Service {
......
...@@ -22,6 +22,9 @@ func (s *server) pingpongHandler(w http.ResponseWriter, r *http.Request) { ...@@ -22,6 +22,9 @@ func (s *server) pingpongHandler(w http.ResponseWriter, r *http.Request) {
peerID := mux.Vars(r)["peer-id"] peerID := mux.Vars(r)["peer-id"]
ctx := r.Context() ctx := r.Context()
span, ctx := s.Tracer.StartSpanFromContext(ctx, "pingpong-api")
defer span.Finish()
address, err := swarm.ParseHexAddress(peerID) address, err := swarm.ParseHexAddress(peerID)
if err != nil { if err != nil {
s.Logger.Debugf("pingpong: parse peer address %s: %v", peerID, err) s.Logger.Debugf("pingpong: parse peer address %s: %v", peerID, err)
......
...@@ -82,7 +82,7 @@ func (s *Service) SetPeerAddedHandler(h func(ctx context.Context, addr swarm.Add ...@@ -82,7 +82,7 @@ func (s *Service) SetPeerAddedHandler(h func(ctx context.Context, addr swarm.Add
} }
func (s *Service) sendPeers(ctx context.Context, peer swarm.Address, peers []swarm.Address) error { func (s *Service) sendPeers(ctx context.Context, peer swarm.Address, peers []swarm.Address) error {
stream, err := s.streamer.NewStream(ctx, peer, protocolName, protocolVersion, peersStreamName) stream, err := s.streamer.NewStream(ctx, peer, nil, protocolName, protocolVersion, peersStreamName)
if err != nil { if err != nil {
return fmt.Errorf("new stream: %w", err) return fmt.Errorf("new stream: %w", err)
} }
...@@ -110,7 +110,7 @@ func (s *Service) sendPeers(ctx context.Context, peer swarm.Address, peers []swa ...@@ -110,7 +110,7 @@ func (s *Service) sendPeers(ctx context.Context, peer swarm.Address, peers []swa
return stream.FullClose() return stream.FullClose()
} }
func (s *Service) peersHandler(peer p2p.Peer, stream p2p.Stream) error { func (s *Service) peersHandler(_ context.Context, peer p2p.Peer, stream p2p.Stream) error {
defer stream.Close() defer stream.Close()
_, r := protobuf.NewWriterAndReader(stream) _, r := protobuf.NewWriterAndReader(stream)
......
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
"github.com/ethersphere/bee/pkg/p2p/libp2p" "github.com/ethersphere/bee/pkg/p2p/libp2p"
"github.com/ethersphere/bee/pkg/pingpong" "github.com/ethersphere/bee/pkg/pingpong"
"github.com/ethersphere/bee/pkg/topology/full" "github.com/ethersphere/bee/pkg/topology/full"
"github.com/ethersphere/bee/pkg/tracing"
ma "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr"
) )
...@@ -38,27 +39,41 @@ type Bee struct { ...@@ -38,27 +39,41 @@ type Bee struct {
apiServer *http.Server apiServer *http.Server
debugAPIServer *http.Server debugAPIServer *http.Server
errorLogWriter *io.PipeWriter errorLogWriter *io.PipeWriter
tracerCloser io.Closer
} }
type Options struct { type Options struct {
DataDir string DataDir string
Password string Password string
APIAddr string APIAddr string
DebugAPIAddr string DebugAPIAddr string
LibP2POptions libp2p.Options LibP2POptions libp2p.Options
Bootnodes []string Bootnodes []string
Logger logging.Logger Logger logging.Logger
TracingEnabled bool
TracingEndpoint string
TracingServiceName string
} }
func NewBee(o Options) (*Bee, error) { func NewBee(o Options) (*Bee, error) {
logger := o.Logger logger := o.Logger
addressbook := inmem.New() addressbook := inmem.New()
tracer, tracerCloser, err := tracing.NewTracer(&tracing.Options{
Enabled: o.TracingEnabled,
Endpoint: o.TracingEndpoint,
ServiceName: o.TracingServiceName,
})
if err != nil {
return nil, fmt.Errorf("tracer: %w", err)
}
p2pCtx, p2pCancel := context.WithCancel(context.Background()) p2pCtx, p2pCancel := context.WithCancel(context.Background())
b := &Bee{ b := &Bee{
p2pCancel: p2pCancel, p2pCancel: p2pCancel,
errorLogWriter: logger.WriterLevel(logrus.ErrorLevel), errorLogWriter: logger.WriterLevel(logrus.ErrorLevel),
tracerCloser: tracerCloser,
} }
var keyStore keystore.Service var keyStore keystore.Service
...@@ -93,6 +108,7 @@ func NewBee(o Options) (*Bee, error) { ...@@ -93,6 +108,7 @@ func NewBee(o Options) (*Bee, error) {
libP2POptions.Overlay = address libP2POptions.Overlay = address
libP2POptions.PrivateKey = libp2pPrivateKey libP2POptions.PrivateKey = libp2pPrivateKey
libP2POptions.Addressbook = addressbook libP2POptions.Addressbook = addressbook
libP2POptions.Tracer = tracer
p2ps, err := libp2p.New(p2pCtx, libP2POptions) p2ps, err := libp2p.New(p2pCtx, libP2POptions)
if err != nil { if err != nil {
return nil, fmt.Errorf("p2p service: %w", err) return nil, fmt.Errorf("p2p service: %w", err)
...@@ -116,6 +132,7 @@ func NewBee(o Options) (*Bee, error) { ...@@ -116,6 +132,7 @@ func NewBee(o Options) (*Bee, error) {
pingPong := pingpong.New(pingpong.Options{ pingPong := pingpong.New(pingpong.Options{
Streamer: p2ps, Streamer: p2ps,
Logger: logger, Logger: logger,
Tracer: tracer,
}) })
if err = p2ps.AddProtocol(pingPong.Protocol()); err != nil { if err = p2ps.AddProtocol(pingPong.Protocol()); err != nil {
...@@ -150,6 +167,7 @@ func NewBee(o Options) (*Bee, error) { ...@@ -150,6 +167,7 @@ func NewBee(o Options) (*Bee, error) {
apiService = api.New(api.Options{ apiService = api.New(api.Options{
Pingpong: pingPong, Pingpong: pingPong,
Logger: logger, Logger: logger,
Tracer: tracer,
}) })
apiListener, err := net.Listen("tcp", o.APIAddr) apiListener, err := net.Listen("tcp", o.APIAddr)
if err != nil { if err != nil {
...@@ -243,5 +261,9 @@ func (b *Bee) Shutdown(ctx context.Context) error { ...@@ -243,5 +261,9 @@ func (b *Bee) Shutdown(ctx context.Context) error {
return fmt.Errorf("p2p server: %w", err) return fmt.Errorf("p2p server: %w", err)
} }
if err := b.tracerCloser.Close(); err != nil {
return fmt.Errorf("tracer: %w", err)
}
return b.errorLogWriter.Close() return b.errorLogWriter.Close()
} }
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package libp2p
import (
"context"
"fmt"
"time"
"github.com/ethersphere/bee/pkg/p2p"
"github.com/ethersphere/bee/pkg/p2p/libp2p/internal/headers/pb"
"github.com/ethersphere/bee/pkg/p2p/protobuf"
)
func sendHeaders(ctx context.Context, headers p2p.Headers, stream *stream) error {
w, r := protobuf.NewWriterAndReader(stream)
if err := w.WriteMsgWithContext(ctx, headersP2PToPB(headers)); err != nil {
return fmt.Errorf("write message: %w", err)
}
h := new(pb.Headers)
if err := r.ReadMsgWithContext(ctx, h); err != nil {
return fmt.Errorf("read message: %w", err)
}
stream.headers = headersPBToP2P(h)
return nil
}
func handleHeaders(headler p2p.HeadlerFunc, stream *stream) error {
w, r := protobuf.NewWriterAndReader(stream)
headers := new(pb.Headers)
if err := r.ReadMsgWithTimeout(time.Second, headers); err != nil {
return fmt.Errorf("read message: %w", err)
}
stream.headers = headersPBToP2P(headers)
var h p2p.Headers
if headler != nil {
h = headler(stream.headers)
}
if err := w.WriteMsgWithTimeout(time.Second, headersP2PToPB(h)); err != nil {
return fmt.Errorf("write message: %w", err)
}
return nil
}
func headersPBToP2P(h *pb.Headers) p2p.Headers {
p2ph := make(p2p.Headers)
for _, rh := range h.Headers {
p2ph[rh.Key] = rh.Value
}
return p2ph
}
func headersP2PToPB(h p2p.Headers) *pb.Headers {
pbh := new(pb.Headers)
pbh.Headers = make([]*pb.Header, 0)
for key, value := range h {
pbh.Headers = append(pbh.Headers, &pb.Header{
Key: key,
Value: value,
})
}
return pbh
}
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package libp2p_test
import (
"context"
"fmt"
"testing"
"time"
"github.com/ethersphere/bee/pkg/p2p"
"github.com/ethersphere/bee/pkg/p2p/libp2p"
)
func TestHeaders(t *testing.T) {
headers := p2p.Headers{
"test-header-key": []byte("header-value"),
"other-key": []byte("other-value"),
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
s1, overlay1, cleanup1 := newService(t, libp2p.Options{})
defer cleanup1()
s2, overlay2, cleanup2 := newService(t, libp2p.Options{})
defer cleanup2()
var gotHeaders p2p.Headers
handled := make(chan struct{})
if err := s1.AddProtocol(newTestProtocol(func(ctx context.Context, p p2p.Peer, stream p2p.Stream) error {
if ctx == nil {
t.Fatal("missing context")
}
if !p.Address.Equal(overlay2) {
t.Fatalf("got peer %v, want %v", p.Address, overlay2)
}
gotHeaders = stream.Headers()
close(handled)
return nil
})); err != nil {
t.Fatal(err)
}
addr := serviceUnderlayAddress(t, s1)
if _, err := s2.Connect(ctx, addr); err != nil {
t.Fatal(err)
}
stream, err := s2.NewStream(ctx, overlay1, headers, testProtocolName, testProtocolVersion, testStreamName)
if err != nil {
t.Fatal(err)
}
defer stream.Close()
select {
case <-handled:
case <-time.After(30 * time.Second):
t.Fatal("timeout waiting for handler")
}
if fmt.Sprint(gotHeaders) != fmt.Sprint(headers) {
t.Errorf("got headers %+v, want %+v", gotHeaders, headers)
}
}
func TestHeaders_empty(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
s1, overlay1, cleanup1 := newService(t, libp2p.Options{})
defer cleanup1()
s2, overlay2, cleanup2 := newService(t, libp2p.Options{})
defer cleanup2()
var gotHeaders p2p.Headers
handled := make(chan struct{})
if err := s1.AddProtocol(newTestProtocol(func(ctx context.Context, p p2p.Peer, stream p2p.Stream) error {
if ctx == nil {
t.Fatal("missing context")
}
if !p.Address.Equal(overlay2) {
t.Fatalf("got peer %v, want %v", p.Address, overlay2)
}
gotHeaders = stream.Headers()
close(handled)
return nil
})); err != nil {
t.Fatal(err)
}
addr := serviceUnderlayAddress(t, s1)
if _, err := s2.Connect(ctx, addr); err != nil {
t.Fatal(err)
}
stream, err := s2.NewStream(ctx, overlay1, nil, testProtocolName, testProtocolVersion, testStreamName)
if err != nil {
t.Fatal(err)
}
defer stream.Close()
select {
case <-handled:
case <-time.After(30 * time.Second):
t.Fatal("timeout waiting for handler")
}
if len(gotHeaders) != 0 {
t.Errorf("got headers %+v, want none", gotHeaders)
}
}
func TestHeadler(t *testing.T) {
receivedHeaders := p2p.Headers{
"test-header-key": []byte("header-value"),
"other-key": []byte("other-value"),
}
sentHeaders := p2p.Headers{
"sent-header-key": []byte("sent-value"),
"other-sent-key": []byte("other-sent-value"),
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
s1, overlay1, cleanup1 := newService(t, libp2p.Options{})
defer cleanup1()
s2, _, cleanup2 := newService(t, libp2p.Options{})
defer cleanup2()
var gotReceivedHeaders p2p.Headers
handled := make(chan struct{})
if err := s1.AddProtocol(p2p.ProtocolSpec{
Name: testProtocolName,
Version: testProtocolVersion,
StreamSpecs: []p2p.StreamSpec{
{
Name: testStreamName,
Handler: func(_ context.Context, _ p2p.Peer, stream p2p.Stream) error {
return nil
},
Headler: func(headers p2p.Headers) p2p.Headers {
defer close(handled)
gotReceivedHeaders = headers
return sentHeaders
},
},
},
}); err != nil {
t.Fatal(err)
}
addr := serviceUnderlayAddress(t, s1)
if _, err := s2.Connect(ctx, addr); err != nil {
t.Fatal(err)
}
stream, err := s2.NewStream(ctx, overlay1, receivedHeaders, testProtocolName, testProtocolVersion, testStreamName)
if err != nil {
t.Fatal(err)
}
defer stream.Close()
select {
case <-handled:
case <-time.After(30 * time.Second):
t.Fatal("timeout waiting for handler")
}
if fmt.Sprint(gotReceivedHeaders) != fmt.Sprint(receivedHeaders) {
t.Errorf("got received headers %+v, want %+v", gotReceivedHeaders, receivedHeaders)
}
gotSentHeaders := stream.Headers()
if fmt.Sprint(gotSentHeaders) != fmt.Sprint(sentHeaders) {
t.Errorf("got sent headers %+v, want %+v", gotSentHeaders, sentHeaders)
}
}
...@@ -4,7 +4,11 @@ ...@@ -4,7 +4,11 @@
package mock package mock
import "bytes" import (
"bytes"
"github.com/ethersphere/bee/pkg/p2p"
)
type Stream struct { type Stream struct {
readBuffer *bytes.Buffer readBuffer *bytes.Buffer
...@@ -48,6 +52,10 @@ func (s *Stream) Write(p []byte) (n int, err error) { ...@@ -48,6 +52,10 @@ func (s *Stream) Write(p []byte) (n int, err error) {
return s.writeBuffer.Write(p) return s.writeBuffer.Write(p)
} }
func (s *Stream) Headers() p2p.Headers {
return nil
}
func (s *Stream) Close() error { func (s *Stream) Close() error {
return nil return nil
} }
......
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:generate sh -c "protoc -I . -I \"$(go list -f '{{ .Dir }}' -m github.com/gogo/protobuf)/protobuf\" --gogofaster_out=. headers.proto"
// Package pb holds only Protocol Buffer definitions and generated code.
package pb
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: headers.proto
package pb
import (
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type Headers struct {
Headers []*Header `protobuf:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty"`
}
func (m *Headers) Reset() { *m = Headers{} }
func (m *Headers) String() string { return proto.CompactTextString(m) }
func (*Headers) ProtoMessage() {}
func (*Headers) Descriptor() ([]byte, []int) {
return fileDescriptor_9cec2a7af668f07b, []int{0}
}
func (m *Headers) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Headers) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Headers.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Headers) XXX_Merge(src proto.Message) {
xxx_messageInfo_Headers.Merge(m, src)
}
func (m *Headers) XXX_Size() int {
return m.Size()
}
func (m *Headers) XXX_DiscardUnknown() {
xxx_messageInfo_Headers.DiscardUnknown(m)
}
var xxx_messageInfo_Headers proto.InternalMessageInfo
func (m *Headers) GetHeaders() []*Header {
if m != nil {
return m.Headers
}
return nil
}
type Header struct {
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
}
func (m *Header) Reset() { *m = Header{} }
func (m *Header) String() string { return proto.CompactTextString(m) }
func (*Header) ProtoMessage() {}
func (*Header) Descriptor() ([]byte, []int) {
return fileDescriptor_9cec2a7af668f07b, []int{1}
}
func (m *Header) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Header.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Header) XXX_Merge(src proto.Message) {
xxx_messageInfo_Header.Merge(m, src)
}
func (m *Header) XXX_Size() int {
return m.Size()
}
func (m *Header) XXX_DiscardUnknown() {
xxx_messageInfo_Header.DiscardUnknown(m)
}
var xxx_messageInfo_Header proto.InternalMessageInfo
func (m *Header) GetKey() string {
if m != nil {
return m.Key
}
return ""
}
func (m *Header) GetValue() []byte {
if m != nil {
return m.Value
}
return nil
}
func init() {
proto.RegisterType((*Headers)(nil), "pb.Headers")
proto.RegisterType((*Header)(nil), "pb.Header")
}
func init() { proto.RegisterFile("headers.proto", fileDescriptor_9cec2a7af668f07b) }
var fileDescriptor_9cec2a7af668f07b = []byte{
// 145 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcd, 0x48, 0x4d, 0x4c,
0x49, 0x2d, 0x2a, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2a, 0x48, 0x52, 0xd2, 0xe7,
0x62, 0xf7, 0x80, 0x08, 0x0a, 0xa9, 0x70, 0xb1, 0x43, 0xe5, 0x25, 0x18, 0x15, 0x98, 0x35, 0xb8,
0x8d, 0xb8, 0xf4, 0x0a, 0x92, 0xf4, 0x20, 0xb2, 0x41, 0x30, 0x29, 0x25, 0x03, 0x2e, 0x36, 0x88,
0x90, 0x90, 0x00, 0x17, 0x73, 0x76, 0x6a, 0xa5, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x88,
0x29, 0x24, 0xc2, 0xc5, 0x5a, 0x96, 0x98, 0x53, 0x9a, 0x2a, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x13,
0x04, 0xe1, 0x38, 0x49, 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72,
0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x12, 0x1b,
0xd8, 0x1d, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x4e, 0xab, 0xdd, 0x98, 0x00, 0x00,
0x00,
}
func (m *Headers) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Headers) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Headers) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Headers) > 0 {
for iNdEx := len(m.Headers) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Headers[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintHeaders(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func (m *Header) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Header) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Header) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Value) > 0 {
i -= len(m.Value)
copy(dAtA[i:], m.Value)
i = encodeVarintHeaders(dAtA, i, uint64(len(m.Value)))
i--
dAtA[i] = 0x12
}
if len(m.Key) > 0 {
i -= len(m.Key)
copy(dAtA[i:], m.Key)
i = encodeVarintHeaders(dAtA, i, uint64(len(m.Key)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintHeaders(dAtA []byte, offset int, v uint64) int {
offset -= sovHeaders(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *Headers) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Headers) > 0 {
for _, e := range m.Headers {
l = e.Size()
n += 1 + l + sovHeaders(uint64(l))
}
}
return n
}
func (m *Header) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Key)
if l > 0 {
n += 1 + l + sovHeaders(uint64(l))
}
l = len(m.Value)
if l > 0 {
n += 1 + l + sovHeaders(uint64(l))
}
return n
}
func sovHeaders(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozHeaders(x uint64) (n int) {
return sovHeaders(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Headers) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowHeaders
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Headers: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Headers: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Headers", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowHeaders
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthHeaders
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthHeaders
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Headers = append(m.Headers, &Header{})
if err := m.Headers[len(m.Headers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipHeaders(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthHeaders
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthHeaders
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Header) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowHeaders
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Header: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Header: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowHeaders
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthHeaders
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthHeaders
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Key = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowHeaders
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthHeaders
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthHeaders
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...)
if m.Value == nil {
m.Value = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipHeaders(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthHeaders
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthHeaders
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipHeaders(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowHeaders
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowHeaders
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowHeaders
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthHeaders
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupHeaders
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthHeaders
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthHeaders = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowHeaders = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupHeaders = fmt.Errorf("proto: unexpected end of group")
)
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
syntax = "proto3";
package pb;
message Headers {
repeated Header headers = 1;
}
message Header {
string key = 1;
bytes value = 2;
}
\ No newline at end of file
...@@ -16,6 +16,7 @@ import ( ...@@ -16,6 +16,7 @@ import (
"github.com/ethersphere/bee/pkg/p2p" "github.com/ethersphere/bee/pkg/p2p"
handshake "github.com/ethersphere/bee/pkg/p2p/libp2p/internal/handshake" handshake "github.com/ethersphere/bee/pkg/p2p/libp2p/internal/handshake"
"github.com/ethersphere/bee/pkg/swarm" "github.com/ethersphere/bee/pkg/swarm"
"github.com/ethersphere/bee/pkg/tracing"
"github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p"
autonat "github.com/libp2p/go-libp2p-autonat-svc" autonat "github.com/libp2p/go-libp2p-autonat-svc"
crypto "github.com/libp2p/go-libp2p-core/crypto" crypto "github.com/libp2p/go-libp2p-core/crypto"
...@@ -36,6 +37,7 @@ import ( ...@@ -36,6 +37,7 @@ import (
var _ p2p.Service = (*Service)(nil) var _ p2p.Service = (*Service)(nil)
type Service struct { type Service struct {
ctx context.Context
host host.Host host host.Host
libp2pPeerstore peerstore.Peerstore libp2pPeerstore peerstore.Peerstore
metrics metrics metrics metrics
...@@ -45,6 +47,7 @@ type Service struct { ...@@ -45,6 +47,7 @@ type Service struct {
peers *peerRegistry peers *peerRegistry
peerHandler func(context.Context, swarm.Address) error peerHandler func(context.Context, swarm.Address) error
logger logging.Logger logger logging.Logger
tracer *tracing.Tracer
} }
type Options struct { type Options struct {
...@@ -56,6 +59,7 @@ type Options struct { ...@@ -56,6 +59,7 @@ type Options struct {
NetworkID int32 NetworkID int32
Addressbook addressbook.Putter Addressbook addressbook.Putter
Logger logging.Logger Logger logging.Logger
Tracer *tracing.Tracer
} }
func New(ctx context.Context, o Options) (*Service, error) { func New(ctx context.Context, o Options) (*Service, error) {
...@@ -149,6 +153,7 @@ func New(ctx context.Context, o Options) (*Service, error) { ...@@ -149,6 +153,7 @@ func New(ctx context.Context, o Options) (*Service, error) {
peerRegistry := newPeerRegistry() peerRegistry := newPeerRegistry()
s := &Service{ s := &Service{
ctx: ctx,
host: h, host: h,
libp2pPeerstore: libp2pPeerstore, libp2pPeerstore: libp2pPeerstore,
metrics: newMetrics(), metrics: newMetrics(),
...@@ -157,6 +162,7 @@ func New(ctx context.Context, o Options) (*Service, error) { ...@@ -157,6 +162,7 @@ func New(ctx context.Context, o Options) (*Service, error) {
peers: peerRegistry, peers: peerRegistry,
addrssbook: o.Addressbook, addrssbook: o.Addressbook,
logger: o.Logger, logger: o.Logger,
tracer: o.Tracer,
} }
// Construct protocols. // Construct protocols.
...@@ -215,8 +221,8 @@ func (s *Service) AddProtocol(p p2p.ProtocolSpec) (err error) { ...@@ -215,8 +221,8 @@ func (s *Service) AddProtocol(p p2p.ProtocolSpec) (err error) {
return fmt.Errorf("protocol version match %s: %w", id, err) return fmt.Errorf("protocol version match %s: %w", id, err)
} }
s.host.SetStreamHandlerMatch(id, matcher, func(stream network.Stream) { s.host.SetStreamHandlerMatch(id, matcher, func(streamlibp2p network.Stream) {
peerID := stream.Conn().RemotePeer() peerID := streamlibp2p.Conn().RemotePeer()
overlay, found := s.peers.overlay(peerID) overlay, found := s.peers.overlay(peerID)
if !found { if !found {
// todo: this should never happen, should we disconnect in this case? // todo: this should never happen, should we disconnect in this case?
...@@ -226,15 +232,31 @@ func (s *Service) AddProtocol(p p2p.ProtocolSpec) (err error) { ...@@ -226,15 +232,31 @@ func (s *Service) AddProtocol(p p2p.ProtocolSpec) (err error) {
return return
} }
stream := newStream(streamlibp2p)
// exchange headers
if err := handleHeaders(ss.Headler, stream); err != nil {
s.logger.Debugf("handle protocol %s/%s: stream %s: peer %s: handle headers: %v", p.Name, p.Version, ss.Name, overlay, err)
return
}
// tracing: get span tracing context and add it to the context
// silently ignore if the peer is not providing tracing
ctx, err := s.tracer.WithContextFromHeaders(s.ctx, stream.Headers())
if err != nil && !errors.Is(err, tracing.ErrContextNotFound) {
s.logger.Debugf("handle protocol %s/%s: stream %s: peer %s: get tracing context: %v", p.Name, p.Version, ss.Name, overlay, err)
return
}
s.metrics.HandledStreamCount.Inc() s.metrics.HandledStreamCount.Inc()
if err := ss.Handler(p2p.Peer{Address: overlay}, newStream(stream)); err != nil { if err := ss.Handler(ctx, p2p.Peer{Address: overlay}, stream); err != nil {
var e *p2p.DisconnectError var e *p2p.DisconnectError
if errors.Is(err, e) { if errors.Is(err, e) {
// todo: test connection close and refactor // todo: test connection close and refactor
_ = s.Disconnect(overlay) _ = s.Disconnect(overlay)
} }
s.logger.Debugf("handle protocol %s/%s: stream %s: peer %s: %w", p.Name, p.Version, ss.Name, overlay, err) s.logger.Debugf("handle protocol %s/%s: stream %s: peer %s: %v", p.Name, p.Version, ss.Name, overlay, err)
} }
}) })
} }
...@@ -313,18 +335,33 @@ func (s *Service) SetPeerAddedHandler(h func(context.Context, swarm.Address) err ...@@ -313,18 +335,33 @@ func (s *Service) SetPeerAddedHandler(h func(context.Context, swarm.Address) err
s.peerHandler = h s.peerHandler = h
} }
func (s *Service) NewStream(ctx context.Context, overlay swarm.Address, protocolName, protocolVersion, streamName string) (p2p.Stream, error) { func (s *Service) NewStream(ctx context.Context, overlay swarm.Address, headers p2p.Headers, protocolName, protocolVersion, streamName string) (p2p.Stream, error) {
peerID, found := s.peers.peerID(overlay) peerID, found := s.peers.peerID(overlay)
if !found { if !found {
return nil, p2p.ErrPeerNotFound return nil, p2p.ErrPeerNotFound
} }
stream, err := s.newStreamForPeerID(ctx, peerID, protocolName, protocolVersion, streamName) streamlibp2p, err := s.newStreamForPeerID(ctx, peerID, protocolName, protocolVersion, streamName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return newStream(stream), nil stream := newStream(streamlibp2p)
// tracing: add span context header
if headers == nil {
headers = make(p2p.Headers)
}
if err := s.tracer.AddContextHeader(ctx, headers); err != nil && !errors.Is(err, tracing.ErrContextNotFound) {
return nil, err
}
// exchange headers
if err := sendHeaders(ctx, headers, stream); err != nil {
return nil, fmt.Errorf("send headers: %w", err)
}
return stream, nil
} }
func (s *Service) newStreamForPeerID(ctx context.Context, peerID libp2ppeer.ID, protocolName, protocolVersion, streamName string) (network.Stream, error) { func (s *Service) newStreamForPeerID(ctx context.Context, peerID libp2ppeer.ID, protocolName, protocolVersion, streamName string) (network.Stream, error) {
......
...@@ -24,7 +24,7 @@ func TestNewStream(t *testing.T) { ...@@ -24,7 +24,7 @@ func TestNewStream(t *testing.T) {
s2, _, cleanup2 := newService(t, libp2p.Options{NetworkID: 1}) s2, _, cleanup2 := newService(t, libp2p.Options{NetworkID: 1})
defer cleanup2() defer cleanup2()
if err := s1.AddProtocol(newTestProtocol(func(p p2p.Peer, stream p2p.Stream) error { if err := s1.AddProtocol(newTestProtocol(func(_ context.Context, _ p2p.Peer, _ p2p.Stream) error {
return nil return nil
})); err != nil { })); err != nil {
t.Fatal(err) t.Fatal(err)
...@@ -36,7 +36,7 @@ func TestNewStream(t *testing.T) { ...@@ -36,7 +36,7 @@ func TestNewStream(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
stream, err := s2.NewStream(ctx, overlay1, testProtocolName, testProtocolVersion, testStreamName) stream, err := s2.NewStream(ctx, overlay1, nil, testProtocolName, testProtocolVersion, testStreamName)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -63,22 +63,22 @@ func TestNewStream_errNotSupported(t *testing.T) { ...@@ -63,22 +63,22 @@ func TestNewStream_errNotSupported(t *testing.T) {
} }
// test for missing protocol // test for missing protocol
_, err := s2.NewStream(ctx, overlay1, testProtocolName, testProtocolVersion, testStreamName) _, err := s2.NewStream(ctx, overlay1, nil, testProtocolName, testProtocolVersion, testStreamName)
expectErrNotSupported(t, err) expectErrNotSupported(t, err)
// add protocol // add protocol
if err := s1.AddProtocol(newTestProtocol(func(_ p2p.Peer, _ p2p.Stream) error { if err := s1.AddProtocol(newTestProtocol(func(_ context.Context, _ p2p.Peer, _ p2p.Stream) error {
return nil return nil
})); err != nil { })); err != nil {
t.Fatal(err) t.Fatal(err)
} }
// test for incorrect protocol name // test for incorrect protocol name
_, err = s2.NewStream(ctx, overlay1, testProtocolName+"invalid", testProtocolVersion, testStreamName) _, err = s2.NewStream(ctx, overlay1, nil, testProtocolName+"invalid", testProtocolVersion, testStreamName)
expectErrNotSupported(t, err) expectErrNotSupported(t, err)
// test for incorrect stream name // test for incorrect stream name
_, err = s2.NewStream(ctx, overlay1, testProtocolName, testProtocolVersion, testStreamName+"invalid") _, err = s2.NewStream(ctx, overlay1, nil, testProtocolName, testProtocolVersion, testStreamName+"invalid")
expectErrNotSupported(t, err) expectErrNotSupported(t, err)
} }
...@@ -98,7 +98,7 @@ func TestNewStream_semanticVersioning(t *testing.T) { ...@@ -98,7 +98,7 @@ func TestNewStream_semanticVersioning(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if err := s1.AddProtocol(newTestProtocol(func(_ p2p.Peer, _ p2p.Stream) error { if err := s1.AddProtocol(newTestProtocol(func(_ context.Context, _ p2p.Peer, _ p2p.Stream) error {
return nil return nil
})); err != nil { })); err != nil {
t.Fatal(err) t.Fatal(err)
...@@ -132,7 +132,7 @@ func TestNewStream_semanticVersioning(t *testing.T) { ...@@ -132,7 +132,7 @@ func TestNewStream_semanticVersioning(t *testing.T) {
{version: "2.4.0", supported: false}, {version: "2.4.0", supported: false},
{version: "3.0.0", supported: false}, {version: "3.0.0", supported: false},
} { } {
_, err := s2.NewStream(ctx, overlay1, testProtocolName, tc.version, testStreamName) _, err := s2.NewStream(ctx, overlay1, nil, testProtocolName, tc.version, testStreamName)
if tc.supported { if tc.supported {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
......
...@@ -5,18 +5,24 @@ ...@@ -5,18 +5,24 @@
package libp2p package libp2p
import ( import (
"github.com/ethersphere/bee/pkg/p2p"
"github.com/libp2p/go-libp2p-core/helpers" "github.com/libp2p/go-libp2p-core/helpers"
"github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/network"
) )
type stream struct { type stream struct {
network.Stream network.Stream
} headers map[string][]byte
func (s *stream) FullClose() error {
return helpers.FullClose(s)
} }
func newStream(s network.Stream) *stream { func newStream(s network.Stream) *stream {
return &stream{Stream: s} return &stream{Stream: s}
} }
func (s *stream) Headers() p2p.Headers {
return s.headers
}
func (s *stream) FullClose() error {
return helpers.FullClose(s)
}
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package libp2p_test
import (
"context"
"fmt"
"testing"
"time"
"github.com/ethersphere/bee/pkg/p2p"
"github.com/ethersphere/bee/pkg/p2p/libp2p"
"github.com/ethersphere/bee/pkg/tracing"
)
func TestTracing(t *testing.T) {
tracer1, closer1, err := tracing.NewTracer(&tracing.Options{
Enabled: true,
ServiceName: "bee-test",
})
if err != nil {
t.Fatal(err)
}
defer closer1.Close()
tracer2, closer2, err := tracing.NewTracer(&tracing.Options{
Enabled: true,
ServiceName: "bee-test",
})
if err != nil {
t.Fatal(err)
}
defer closer2.Close()
s1, overlay1, cleanup1 := newService(t, libp2p.Options{})
defer cleanup1()
s2, _, cleanup2 := newService(t, libp2p.Options{})
defer cleanup2()
var handledTracingSpan string
handled := make(chan struct{})
if err := s1.AddProtocol(newTestProtocol(func(ctx context.Context, _ p2p.Peer, _ p2p.Stream) error {
span, _ := tracer1.StartSpanFromContext(ctx, "test-p2p-handler")
defer span.Finish()
handledTracingSpan = fmt.Sprint(span.Context())
close(handled)
return nil
})); err != nil {
t.Fatal(err)
}
addr := serviceUnderlayAddress(t, s1)
connectContext, connectCancel := context.WithCancel(context.Background())
defer connectCancel()
if _, err := s2.Connect(connectContext, addr); err != nil {
t.Fatal(err)
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
span, ctx := tracer2.StartSpanFromContext(ctx, "test-p2p-client")
defer span.Finish()
if fmt.Sprint(span.Context()) == "" {
t.Error("not tracing span context to send")
}
stream, err := s2.NewStream(ctx, overlay1, nil, testProtocolName, testProtocolVersion, testStreamName)
if err != nil {
t.Fatal(err)
}
defer stream.Close()
select {
case <-handled:
case <-time.After(30 * time.Second):
t.Fatal("timeout waiting for handler")
}
if handledTracingSpan == "" {
t.Error("got not tracing span context in handler")
}
}
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
ma "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr"
) )
// Service provides methods to handle p2p Peers and Protocols.
type Service interface { type Service interface {
AddProtocol(ProtocolSpec) error AddProtocol(ProtocolSpec) error
Connect(ctx context.Context, addr ma.Multiaddr) (overlay swarm.Address, err error) Connect(ctx context.Context, addr ma.Multiaddr) (overlay swarm.Address, err error)
...@@ -20,35 +21,58 @@ type Service interface { ...@@ -20,35 +21,58 @@ type Service interface {
SetPeerAddedHandler(func(context.Context, swarm.Address) error) SetPeerAddedHandler(func(context.Context, swarm.Address) error)
} }
// Streamer is able to create a new Stream.
type Streamer interface { type Streamer interface {
NewStream(ctx context.Context, address swarm.Address, protocol, version, stream string) (Stream, error) NewStream(ctx context.Context, address swarm.Address, h Headers, protocol, version, stream string) (Stream, error)
} }
// Stream represent a bidirectional data Stream.
type Stream interface { type Stream interface {
io.ReadWriter io.ReadWriter
io.Closer io.Closer
Headers() Headers
FullClose() error FullClose() error
} }
// ProtocolSpec defines a collection of Stream specifications with handlers.
type ProtocolSpec struct { type ProtocolSpec struct {
Name string Name string
Version string Version string
StreamSpecs []StreamSpec StreamSpecs []StreamSpec
} }
// StreamSpec defines a Stream handling within the protocol.
type StreamSpec struct { type StreamSpec struct {
Name string Name string
Handler HandlerFunc Handler HandlerFunc
Headler HeadlerFunc
} }
// Peer holds information about a Peer.
type Peer struct { type Peer struct {
Address swarm.Address Address swarm.Address
} }
type HandlerFunc func(Peer, Stream) error // HandlerFunc handles a received Stream from a Peer.
type HandlerFunc func(context.Context, Peer, Stream) error
// HandlerMiddleware decorates a HandlerFunc by returning a new one.
type HandlerMiddleware func(HandlerFunc) HandlerFunc type HandlerMiddleware func(HandlerFunc) HandlerFunc
// HeadlerFunc is returning response headers based on the received request
// headers.
type HeadlerFunc func(Headers) Headers
// Headers represents a collection of p2p header key value pairs.
type Headers map[string][]byte
// Common header names.
const (
HeaderNameTracingSpanContext = "tracing-span-context"
)
// NewSwarmStreamName constructs a libp2p compatible stream name out of
// protocol name and version and stream name.
func NewSwarmStreamName(protocol, version, stream string) string { func NewSwarmStreamName(protocol, version, stream string) string {
return "/swarm/" + protocol + "/" + version + "/" + stream return "/swarm/" + protocol + "/" + version + "/" + stream
} }
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/ethersphere/bee/pkg/p2p"
"github.com/ethersphere/bee/pkg/p2p/protobuf" "github.com/ethersphere/bee/pkg/p2p/protobuf"
"github.com/ethersphere/bee/pkg/p2p/protobuf/internal/pb" "github.com/ethersphere/bee/pkg/p2p/protobuf/internal/pb"
) )
...@@ -359,6 +360,10 @@ func (noopWriteCloser) Write(p []byte) (n int, err error) { ...@@ -359,6 +360,10 @@ func (noopWriteCloser) Write(p []byte) (n int, err error) {
return 0, nil return 0, nil
} }
func (noopWriteCloser) Headers() p2p.Headers {
return nil
}
func (noopWriteCloser) Close() error { func (noopWriteCloser) Close() error {
return nil return nil
} }
...@@ -379,6 +384,10 @@ func (noopReadCloser) Read(p []byte) (n int, err error) { ...@@ -379,6 +384,10 @@ func (noopReadCloser) Read(p []byte) (n int, err error) {
return 0, nil return 0, nil
} }
func (noopReadCloser) Headers() p2p.Headers {
return nil
}
func (noopReadCloser) Close() error { func (noopReadCloser) Close() error {
return nil return nil
} }
......
...@@ -52,7 +52,7 @@ func New(opts ...Option) *Recorder { ...@@ -52,7 +52,7 @@ func New(opts ...Option) *Recorder {
return r return r
} }
func (r *Recorder) NewStream(_ context.Context, addr swarm.Address, protocolName, protocolVersion, streamName string) (p2p.Stream, error) { func (r *Recorder) NewStream(ctx context.Context, addr swarm.Address, h p2p.Headers, protocolName, protocolVersion, streamName string) (p2p.Stream, error) {
recordIn := newRecord() recordIn := newRecord()
recordOut := newRecord() recordOut := newRecord()
closedIn := make(chan struct{}) closedIn := make(chan struct{})
...@@ -61,11 +61,13 @@ func (r *Recorder) NewStream(_ context.Context, addr swarm.Address, protocolName ...@@ -61,11 +61,13 @@ func (r *Recorder) NewStream(_ context.Context, addr swarm.Address, protocolName
streamIn := newStream(recordOut, recordIn, closedOut, closedIn) streamIn := newStream(recordOut, recordIn, closedOut, closedIn)
var handler p2p.HandlerFunc var handler p2p.HandlerFunc
var headler p2p.HeadlerFunc
for _, p := range r.protocols { for _, p := range r.protocols {
if p.Name == protocolName && p.Version == protocolVersion { if p.Name == protocolName && p.Version == protocolVersion {
for _, s := range p.StreamSpecs { for _, s := range p.StreamSpecs {
if s.Name == streamName { if s.Name == streamName {
handler = s.Handler handler = s.Handler
headler = s.Headler
} }
} }
} }
...@@ -76,9 +78,12 @@ func (r *Recorder) NewStream(_ context.Context, addr swarm.Address, protocolName ...@@ -76,9 +78,12 @@ func (r *Recorder) NewStream(_ context.Context, addr swarm.Address, protocolName
for i := len(r.middlewares) - 1; i >= 0; i-- { for i := len(r.middlewares) - 1; i >= 0; i-- {
handler = r.middlewares[i](handler) handler = r.middlewares[i](handler)
} }
if headler != nil {
streamOut.headers = headler(h)
}
record := &Record{in: recordIn, out: recordOut} record := &Record{in: recordIn, out: recordOut}
go func() { go func() {
err := handler(p2p.Peer{Address: addr}, streamIn) err := handler(ctx, p2p.Peer{Address: addr}, streamIn)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
record.setErr(err) record.setErr(err)
} }
...@@ -138,6 +143,7 @@ func (r *Record) setErr(err error) { ...@@ -138,6 +143,7 @@ func (r *Record) setErr(err error) {
type stream struct { type stream struct {
in io.WriteCloser in io.WriteCloser
out io.ReadCloser out io.ReadCloser
headers p2p.Headers
cin chan struct{} cin chan struct{}
cout chan struct{} cout chan struct{}
closeOnce sync.Once closeOnce sync.Once
...@@ -155,6 +161,10 @@ func (s *stream) Write(p []byte) (int, error) { ...@@ -155,6 +161,10 @@ func (s *stream) Write(p []byte) (int, error) {
return s.in.Write(p) return s.in.Write(p)
} }
func (s *stream) Headers() p2p.Headers {
return s.headers
}
func (s *stream) Close() error { func (s *stream) Close() error {
var e error var e error
s.closeOnce.Do(func() { s.closeOnce.Do(func() {
......
...@@ -31,7 +31,7 @@ func TestRecorder(t *testing.T) { ...@@ -31,7 +31,7 @@ func TestRecorder(t *testing.T) {
recorder := streamtest.New( recorder := streamtest.New(
streamtest.WithProtocols( streamtest.WithProtocols(
newTestProtocol(func(peer p2p.Peer, stream p2p.Stream) error { newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error {
rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))
for { for {
q, err := rw.ReadString('\n') q, err := rw.ReadString('\n')
...@@ -55,7 +55,7 @@ func TestRecorder(t *testing.T) { ...@@ -55,7 +55,7 @@ func TestRecorder(t *testing.T) {
) )
ask := func(ctx context.Context, s p2p.Streamer, address swarm.Address, questions ...string) (answers []string, err error) { ask := func(ctx context.Context, s p2p.Streamer, address swarm.Address, questions ...string) (answers []string, err error) {
stream, err := s.NewStream(ctx, address, testProtocolName, testProtocolVersion, testStreamName) stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName)
if err != nil { if err != nil {
return nil, fmt.Errorf("new stream: %w", err) return nil, fmt.Errorf("new stream: %w", err)
} }
...@@ -115,7 +115,7 @@ func TestRecorder(t *testing.T) { ...@@ -115,7 +115,7 @@ func TestRecorder(t *testing.T) {
func TestRecorder_errStreamNotSupported(t *testing.T) { func TestRecorder_errStreamNotSupported(t *testing.T) {
r := streamtest.New() r := streamtest.New()
_, err := r.NewStream(context.Background(), swarm.ZeroAddress, "testing", "messages", "1.0.1") _, err := r.NewStream(context.Background(), swarm.ZeroAddress, nil, "testing", "messages", "1.0.1")
if !errors.Is(err, streamtest.ErrStreamNotSupported) { if !errors.Is(err, streamtest.ErrStreamNotSupported) {
t.Fatalf("got error %v, want %v", err, streamtest.ErrStreamNotSupported) t.Fatalf("got error %v, want %v", err, streamtest.ErrStreamNotSupported)
} }
...@@ -124,7 +124,7 @@ func TestRecorder_errStreamNotSupported(t *testing.T) { ...@@ -124,7 +124,7 @@ func TestRecorder_errStreamNotSupported(t *testing.T) {
func TestRecorder_fullcloseWithRemoteClose(t *testing.T) { func TestRecorder_fullcloseWithRemoteClose(t *testing.T) {
recorder := streamtest.New( recorder := streamtest.New(
streamtest.WithProtocols( streamtest.WithProtocols(
newTestProtocol(func(peer p2p.Peer, stream p2p.Stream) error { newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error {
defer stream.Close() defer stream.Close()
_, err := bufio.NewReader(stream).ReadString('\n') _, err := bufio.NewReader(stream).ReadString('\n')
return err return err
...@@ -133,7 +133,7 @@ func TestRecorder_fullcloseWithRemoteClose(t *testing.T) { ...@@ -133,7 +133,7 @@ func TestRecorder_fullcloseWithRemoteClose(t *testing.T) {
) )
request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) { request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) {
stream, err := s.NewStream(ctx, address, testProtocolName, testProtocolVersion, testStreamName) stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName)
if err != nil { if err != nil {
return fmt.Errorf("new stream: %w", err) return fmt.Errorf("new stream: %w", err)
} }
...@@ -171,7 +171,7 @@ func TestRecorder_fullcloseWithoutRemoteClose(t *testing.T) { ...@@ -171,7 +171,7 @@ func TestRecorder_fullcloseWithoutRemoteClose(t *testing.T) {
defer streamtest.ResetFullCloseTimeout() defer streamtest.ResetFullCloseTimeout()
recorder := streamtest.New( recorder := streamtest.New(
streamtest.WithProtocols( streamtest.WithProtocols(
newTestProtocol(func(peer p2p.Peer, stream p2p.Stream) error { newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error {
// don't close the stream here to initiate timeout // don't close the stream here to initiate timeout
// just try to read the message that it terminated with // just try to read the message that it terminated with
// a new line character // a new line character
...@@ -182,7 +182,7 @@ func TestRecorder_fullcloseWithoutRemoteClose(t *testing.T) { ...@@ -182,7 +182,7 @@ func TestRecorder_fullcloseWithoutRemoteClose(t *testing.T) {
) )
request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) { request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) {
stream, err := s.NewStream(ctx, address, testProtocolName, testProtocolVersion, testStreamName) stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName)
if err != nil { if err != nil {
return fmt.Errorf("new stream: %w", err) return fmt.Errorf("new stream: %w", err)
} }
...@@ -218,7 +218,7 @@ func TestRecorder_fullcloseWithoutRemoteClose(t *testing.T) { ...@@ -218,7 +218,7 @@ func TestRecorder_fullcloseWithoutRemoteClose(t *testing.T) {
func TestRecorder_multipleParallelFullCloseAndClose(t *testing.T) { func TestRecorder_multipleParallelFullCloseAndClose(t *testing.T) {
recorder := streamtest.New( recorder := streamtest.New(
streamtest.WithProtocols( streamtest.WithProtocols(
newTestProtocol(func(peer p2p.Peer, stream p2p.Stream) error { newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error {
if _, err := bufio.NewReader(stream).ReadString('\n'); err != nil { if _, err := bufio.NewReader(stream).ReadString('\n'); err != nil {
return err return err
} }
...@@ -237,7 +237,7 @@ func TestRecorder_multipleParallelFullCloseAndClose(t *testing.T) { ...@@ -237,7 +237,7 @@ func TestRecorder_multipleParallelFullCloseAndClose(t *testing.T) {
) )
request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) { request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) {
stream, err := s.NewStream(ctx, address, testProtocolName, testProtocolVersion, testStreamName) stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName)
if err != nil { if err != nil {
return fmt.Errorf("new stream: %w", err) return fmt.Errorf("new stream: %w", err)
} }
...@@ -281,7 +281,7 @@ func TestRecorder_multipleParallelFullCloseAndClose(t *testing.T) { ...@@ -281,7 +281,7 @@ func TestRecorder_multipleParallelFullCloseAndClose(t *testing.T) {
func TestRecorder_closeAfterPartialWrite(t *testing.T) { func TestRecorder_closeAfterPartialWrite(t *testing.T) {
recorder := streamtest.New( recorder := streamtest.New(
streamtest.WithProtocols( streamtest.WithProtocols(
newTestProtocol(func(peer p2p.Peer, stream p2p.Stream) error { newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error {
// just try to read the message that it terminated with // just try to read the message that it terminated with
// a new line character // a new line character
_, err := bufio.NewReader(stream).ReadString('\n') _, err := bufio.NewReader(stream).ReadString('\n')
...@@ -291,7 +291,7 @@ func TestRecorder_closeAfterPartialWrite(t *testing.T) { ...@@ -291,7 +291,7 @@ func TestRecorder_closeAfterPartialWrite(t *testing.T) {
) )
request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) { request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) {
stream, err := s.NewStream(ctx, address, testProtocolName, testProtocolVersion, testStreamName) stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName)
if err != nil { if err != nil {
return fmt.Errorf("new stream: %w", err) return fmt.Errorf("new stream: %w", err)
} }
...@@ -343,7 +343,7 @@ func TestRecorder_closeAfterPartialWrite(t *testing.T) { ...@@ -343,7 +343,7 @@ func TestRecorder_closeAfterPartialWrite(t *testing.T) {
func TestRecorder_withMiddlewares(t *testing.T) { func TestRecorder_withMiddlewares(t *testing.T) {
recorder := streamtest.New( recorder := streamtest.New(
streamtest.WithProtocols( streamtest.WithProtocols(
newTestProtocol(func(peer p2p.Peer, stream p2p.Stream) error { newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error {
rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))
if _, err := rw.ReadString('\n'); err != nil { if _, err := rw.ReadString('\n'); err != nil {
...@@ -362,8 +362,8 @@ func TestRecorder_withMiddlewares(t *testing.T) { ...@@ -362,8 +362,8 @@ func TestRecorder_withMiddlewares(t *testing.T) {
), ),
streamtest.WithMiddlewares( streamtest.WithMiddlewares(
func(h p2p.HandlerFunc) p2p.HandlerFunc { func(h p2p.HandlerFunc) p2p.HandlerFunc {
return func(peer p2p.Peer, stream p2p.Stream) error { return func(ctx context.Context, peer p2p.Peer, stream p2p.Stream) error {
if err := h(peer, stream); err != nil { if err := h(ctx, peer, stream); err != nil {
return err return err
} }
// close stream after all previous middlewares wrote to it // close stream after all previous middlewares wrote to it
...@@ -372,11 +372,11 @@ func TestRecorder_withMiddlewares(t *testing.T) { ...@@ -372,11 +372,11 @@ func TestRecorder_withMiddlewares(t *testing.T) {
} }
}, },
func(h p2p.HandlerFunc) p2p.HandlerFunc { func(h p2p.HandlerFunc) p2p.HandlerFunc {
return func(peer p2p.Peer, stream p2p.Stream) error { return func(ctx context.Context, peer p2p.Peer, stream p2p.Stream) error {
if _, err := stream.Write([]byte("pre 1, ")); err != nil { if _, err := stream.Write([]byte("pre 1, ")); err != nil {
return err return err
} }
if err := h(peer, stream); err != nil { if err := h(ctx, peer, stream); err != nil {
return err return err
} }
if _, err := stream.Write([]byte("post 1, ")); err != nil { if _, err := stream.Write([]byte("post 1, ")); err != nil {
...@@ -386,11 +386,11 @@ func TestRecorder_withMiddlewares(t *testing.T) { ...@@ -386,11 +386,11 @@ func TestRecorder_withMiddlewares(t *testing.T) {
} }
}, },
func(h p2p.HandlerFunc) p2p.HandlerFunc { func(h p2p.HandlerFunc) p2p.HandlerFunc {
return func(peer p2p.Peer, stream p2p.Stream) error { return func(ctx context.Context, peer p2p.Peer, stream p2p.Stream) error {
if _, err := stream.Write([]byte("pre 2, ")); err != nil { if _, err := stream.Write([]byte("pre 2, ")); err != nil {
return err return err
} }
if err := h(peer, stream); err != nil { if err := h(ctx, peer, stream); err != nil {
return err return err
} }
if _, err := stream.Write([]byte("post 2, ")); err != nil { if _, err := stream.Write([]byte("post 2, ")); err != nil {
...@@ -402,11 +402,11 @@ func TestRecorder_withMiddlewares(t *testing.T) { ...@@ -402,11 +402,11 @@ func TestRecorder_withMiddlewares(t *testing.T) {
), ),
streamtest.WithMiddlewares( streamtest.WithMiddlewares(
func(h p2p.HandlerFunc) p2p.HandlerFunc { func(h p2p.HandlerFunc) p2p.HandlerFunc {
return func(peer p2p.Peer, stream p2p.Stream) error { return func(ctx context.Context, peer p2p.Peer, stream p2p.Stream) error {
if _, err := stream.Write([]byte("pre 3, ")); err != nil { if _, err := stream.Write([]byte("pre 3, ")); err != nil {
return err return err
} }
if err := h(peer, stream); err != nil { if err := h(ctx, peer, stream); err != nil {
return err return err
} }
if _, err := stream.Write([]byte("post 3, ")); err != nil { if _, err := stream.Write([]byte("post 3, ")); err != nil {
...@@ -419,7 +419,7 @@ func TestRecorder_withMiddlewares(t *testing.T) { ...@@ -419,7 +419,7 @@ func TestRecorder_withMiddlewares(t *testing.T) {
) )
request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) error { request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) error {
stream, err := s.NewStream(ctx, address, testProtocolName, testProtocolVersion, testStreamName) stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName)
if err != nil { if err != nil {
return fmt.Errorf("new stream: %w", err) return fmt.Errorf("new stream: %w", err)
} }
...@@ -460,7 +460,7 @@ func TestRecorder_recordErr(t *testing.T) { ...@@ -460,7 +460,7 @@ func TestRecorder_recordErr(t *testing.T) {
recorder := streamtest.New( recorder := streamtest.New(
streamtest.WithProtocols( streamtest.WithProtocols(
newTestProtocol(func(peer p2p.Peer, stream p2p.Stream) error { newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error {
rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))
defer stream.Close() defer stream.Close()
...@@ -481,7 +481,7 @@ func TestRecorder_recordErr(t *testing.T) { ...@@ -481,7 +481,7 @@ func TestRecorder_recordErr(t *testing.T) {
) )
request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) { request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) {
stream, err := s.NewStream(ctx, address, testProtocolName, testProtocolVersion, testStreamName) stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName)
if err != nil { if err != nil {
return fmt.Errorf("new stream: %w", err) return fmt.Errorf("new stream: %w", err)
} }
......
...@@ -15,6 +15,7 @@ import ( ...@@ -15,6 +15,7 @@ import (
"github.com/ethersphere/bee/pkg/p2p/protobuf" "github.com/ethersphere/bee/pkg/p2p/protobuf"
"github.com/ethersphere/bee/pkg/pingpong/pb" "github.com/ethersphere/bee/pkg/pingpong/pb"
"github.com/ethersphere/bee/pkg/swarm" "github.com/ethersphere/bee/pkg/swarm"
"github.com/ethersphere/bee/pkg/tracing"
) )
const ( const (
...@@ -30,18 +31,21 @@ type Interface interface { ...@@ -30,18 +31,21 @@ type Interface interface {
type Service struct { type Service struct {
streamer p2p.Streamer streamer p2p.Streamer
logger logging.Logger logger logging.Logger
tracer *tracing.Tracer
metrics metrics metrics metrics
} }
type Options struct { type Options struct {
Streamer p2p.Streamer Streamer p2p.Streamer
Logger logging.Logger Logger logging.Logger
Tracer *tracing.Tracer
} }
func New(o Options) *Service { func New(o Options) *Service {
return &Service{ return &Service{
streamer: o.Streamer, streamer: o.Streamer,
logger: o.Logger, logger: o.Logger,
tracer: o.Tracer,
metrics: newMetrics(), metrics: newMetrics(),
} }
} }
...@@ -53,15 +57,18 @@ func (s *Service) Protocol() p2p.ProtocolSpec { ...@@ -53,15 +57,18 @@ func (s *Service) Protocol() p2p.ProtocolSpec {
StreamSpecs: []p2p.StreamSpec{ StreamSpecs: []p2p.StreamSpec{
{ {
Name: streamName, Name: streamName,
Handler: s.Handler, Handler: s.handler,
}, },
}, },
} }
} }
func (s *Service) Ping(ctx context.Context, address swarm.Address, msgs ...string) (rtt time.Duration, err error) { func (s *Service) Ping(ctx context.Context, address swarm.Address, msgs ...string) (rtt time.Duration, err error) {
span, ctx := s.tracer.StartSpanFromContext(ctx, "pingpong-p2p-ping")
defer span.Finish()
start := time.Now() start := time.Now()
stream, err := s.streamer.NewStream(ctx, address, protocolName, protocolVersion, streamName) stream, err := s.streamer.NewStream(ctx, address, nil, protocolName, protocolVersion, streamName)
if err != nil { if err != nil {
return 0, fmt.Errorf("new stream: %w", err) return 0, fmt.Errorf("new stream: %w", err)
} }
...@@ -91,10 +98,13 @@ func (s *Service) Ping(ctx context.Context, address swarm.Address, msgs ...strin ...@@ -91,10 +98,13 @@ func (s *Service) Ping(ctx context.Context, address swarm.Address, msgs ...strin
return time.Since(start), nil return time.Since(start), nil
} }
func (s *Service) Handler(peer p2p.Peer, stream p2p.Stream) error { func (s *Service) handler(ctx context.Context, p p2p.Peer, stream p2p.Stream) error {
w, r := protobuf.NewWriterAndReader(stream) w, r := protobuf.NewWriterAndReader(stream)
defer stream.Close() defer stream.Close()
span, ctx := s.tracer.StartSpanFromContext(ctx, "pingpong-p2p-handler")
defer span.Finish()
var ping pb.Ping var ping pb.Ping
for { for {
if err := r.ReadMsg(&ping); err != nil { if err := r.ReadMsg(&ping); err != nil {
...@@ -106,7 +116,7 @@ func (s *Service) Handler(peer p2p.Peer, stream p2p.Stream) error { ...@@ -106,7 +116,7 @@ func (s *Service) Handler(peer p2p.Peer, stream p2p.Stream) error {
s.logger.Tracef("got ping: %q", ping.Greeting) s.logger.Tracef("got ping: %q", ping.Greeting)
s.metrics.PingReceivedCount.Inc() s.metrics.PingReceivedCount.Inc()
if err := w.WriteMsg(&pb.Pong{ if err := w.WriteMsgWithContext(ctx, &pb.Pong{
Response: "{" + ping.Greeting + "}", Response: "{" + ping.Greeting + "}",
}); err != nil { }); err != nil {
return fmt.Errorf("write message: %w", err) return fmt.Errorf("write message: %w", err)
......
...@@ -56,7 +56,7 @@ func (s *Service) Protocol() p2p.ProtocolSpec { ...@@ -56,7 +56,7 @@ func (s *Service) Protocol() p2p.ProtocolSpec {
StreamSpecs: []p2p.StreamSpec{ StreamSpecs: []p2p.StreamSpec{
{ {
Name: streamName, Name: streamName,
Handler: s.Handler, Handler: s.handler,
}, },
}, },
} }
...@@ -67,7 +67,7 @@ func (s *Service) RetrieveChunk(ctx context.Context, addr swarm.Address) (data [ ...@@ -67,7 +67,7 @@ func (s *Service) RetrieveChunk(ctx context.Context, addr swarm.Address) (data [
if err != nil { if err != nil {
return nil, err return nil, err
} }
stream, err := s.streamer.NewStream(ctx, peerID, protocolName, protocolVersion, streamName) stream, err := s.streamer.NewStream(ctx, peerID, nil, protocolName, protocolVersion, streamName)
if err != nil { if err != nil {
return nil, fmt.Errorf("new stream: %w", err) return nil, fmt.Errorf("new stream: %w", err)
} }
...@@ -89,7 +89,7 @@ func (s *Service) RetrieveChunk(ctx context.Context, addr swarm.Address) (data [ ...@@ -89,7 +89,7 @@ func (s *Service) RetrieveChunk(ctx context.Context, addr swarm.Address) (data [
return d.Data, nil return d.Data, nil
} }
func (s *Service) Handler(p p2p.Peer, stream p2p.Stream) error { func (s *Service) handler(ctx context.Context, p p2p.Peer, stream p2p.Stream) error {
w, r := protobuf.NewWriterAndReader(stream) w, r := protobuf.NewWriterAndReader(stream)
defer stream.Close() defer stream.Close()
var req pb.Request var req pb.Request
...@@ -102,7 +102,7 @@ func (s *Service) Handler(p p2p.Peer, stream p2p.Stream) error { ...@@ -102,7 +102,7 @@ func (s *Service) Handler(p p2p.Peer, stream p2p.Stream) error {
return err return err
} }
if err := w.WriteMsg(&pb.Delivery{ if err := w.WriteMsgWithContext(ctx, &pb.Delivery{
Data: data, Data: data,
}); err != nil { }); err != nil {
return err return err
......
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package tracing
import (
"bufio"
"bytes"
"context"
"errors"
"io"
"time"
"github.com/ethersphere/bee/pkg/p2p"
"github.com/opentracing/opentracing-go"
"github.com/uber/jaeger-client-go"
"github.com/uber/jaeger-client-go/config"
)
var (
// ErrContextNotFound is returned when tracing context is not present
// in p2p Headers or context.
ErrContextNotFound = errors.New("tracing context not found")
// contextKey is used to reference a tracing context span as context value.
contextKey = struct{}{}
// noopTracer is the tracer that does nothing to handle a nil Tracer usage.
noopTracer = &Tracer{tracer: new(opentracing.NoopTracer)}
)
// Tracer connect to a tracing server and handles tracing spans and contexts
// by using opentracing Tracer.
type Tracer struct {
tracer opentracing.Tracer
}
// Options are optional parameters for Tracer constructor.
type Options struct {
Enabled bool
Endpoint string
ServiceName string
}
// NewTracer creates a new Tracer and returns a closer which needs to be closed
// when the Tracer is no longer used to flush remaining traces.
func NewTracer(o *Options) (*Tracer, io.Closer, error) {
if o == nil {
o = new(Options)
}
cfg := config.Configuration{
Disabled: !o.Enabled,
ServiceName: o.ServiceName,
Sampler: &config.SamplerConfig{
Type: jaeger.SamplerTypeConst,
Param: 1,
},
Reporter: &config.ReporterConfig{
LogSpans: true,
BufferFlushInterval: 1 * time.Second,
LocalAgentHostPort: o.Endpoint,
},
}
t, closer, err := cfg.NewTracer()
if err != nil {
return nil, nil, err
}
return &Tracer{tracer: t}, closer, nil
}
// StartSpanFromContext starts a new tracing span that is either a root one or a
// child of existing one from the provided Context.
func (t *Tracer) StartSpanFromContext(ctx context.Context, operationName string, opts ...opentracing.StartSpanOption) (opentracing.Span, context.Context) {
if t == nil {
t = noopTracer
}
var span opentracing.Span
if parentContext := FromContext(ctx); parentContext != nil {
opts = append(opts, opentracing.ChildOf(parentContext))
span = t.tracer.StartSpan(operationName, opts...)
} else {
span = t.tracer.StartSpan(operationName, opts...)
}
return span, WithContext(ctx, span.Context())
}
// AddContextHeader adds a tracing span context to provided p2p Headers from
// the go context. If the tracing span context is not present in go context,
// ErrContextNotFound is returned.
func (t *Tracer) AddContextHeader(ctx context.Context, headers p2p.Headers) error {
if t == nil {
t = noopTracer
}
c := FromContext(ctx)
if c == nil {
return ErrContextNotFound
}
var b bytes.Buffer
w := bufio.NewWriter(&b)
if err := t.tracer.Inject(c, opentracing.Binary, w); err != nil {
return err
}
if err := w.Flush(); err != nil {
return err
}
headers[p2p.HeaderNameTracingSpanContext] = b.Bytes()
return nil
}
// FromHeaders returns tracing span context from p2p Headers. If the tracing
// span context is not present in go context, ErrContextNotFound is returned.
func (t *Tracer) FromHeaders(headers p2p.Headers) (opentracing.SpanContext, error) {
if t == nil {
t = noopTracer
}
v := headers[p2p.HeaderNameTracingSpanContext]
if v == nil {
return nil, ErrContextNotFound
}
c, err := t.tracer.Extract(opentracing.Binary, bytes.NewReader(v))
if err != nil {
if errors.Is(err, opentracing.ErrSpanContextNotFound) {
return nil, ErrContextNotFound
}
return nil, err
}
return c, nil
}
// WithContextFromHeaders returns a new context with injected tracing span
// context if they are found in p2p Headers. If the tracing span context is not
// present in go context, ErrContextNotFound is returned.
func (t *Tracer) WithContextFromHeaders(ctx context.Context, headers p2p.Headers) (context.Context, error) {
if t == nil {
t = noopTracer
}
c, err := t.FromHeaders(headers)
if err != nil {
return ctx, err
}
return WithContext(ctx, c), nil
}
// WithContext adds tracing span context to go context.
func WithContext(ctx context.Context, c opentracing.SpanContext) context.Context {
return context.WithValue(ctx, contextKey, c)
}
// FromContext return tracing span context from go context. If the tracing span
// context is not present in go context, nil is returned.
func FromContext(ctx context.Context) opentracing.SpanContext {
c, ok := ctx.Value(contextKey).(opentracing.SpanContext)
if !ok {
return nil
}
return c
}
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package tracing_test
import (
"context"
"fmt"
"io"
"testing"
"github.com/ethersphere/bee/pkg/p2p"
"github.com/ethersphere/bee/pkg/tracing"
)
func TestSpanFromHeaders(t *testing.T) {
tracer, closer := newTracer(t)
defer closer.Close()
span, ctx := tracer.StartSpanFromContext(context.Background(), "some-operation")
defer span.Finish()
headers := make(p2p.Headers)
if err := tracer.AddContextHeader(ctx, headers); err != nil {
t.Fatal(err)
}
gotSpanContext, err := tracer.FromHeaders(headers)
if err != nil {
t.Fatal(err)
}
if fmt.Sprint(gotSpanContext) == "" {
t.Fatal("got empty span context")
}
wantSpanContext := span.Context()
if fmt.Sprint(wantSpanContext) == "" {
t.Fatal("got empty start span context")
}
if fmt.Sprint(gotSpanContext) != fmt.Sprint(wantSpanContext) {
t.Errorf("got span context %+v, want %+v", gotSpanContext, wantSpanContext)
}
}
func TestSpanWithContextFromHeaders(t *testing.T) {
tracer, closer := newTracer(t)
defer closer.Close()
span, ctx := tracer.StartSpanFromContext(context.Background(), "some-operation")
defer span.Finish()
headers := make(p2p.Headers)
if err := tracer.AddContextHeader(ctx, headers); err != nil {
t.Fatal(err)
}
ctx, err := tracer.WithContextFromHeaders(context.Background(), headers)
if err != nil {
t.Fatal(err)
}
gotSpanContext := tracing.FromContext(ctx)
if fmt.Sprint(gotSpanContext) == "" {
t.Fatal("got empty span context")
}
wantSpanContext := span.Context()
if fmt.Sprint(wantSpanContext) == "" {
t.Fatal("got empty start span context")
}
if fmt.Sprint(gotSpanContext) != fmt.Sprint(wantSpanContext) {
t.Errorf("got span context %+v, want %+v", gotSpanContext, wantSpanContext)
}
}
func TestFromContext(t *testing.T) {
tracer, closer := newTracer(t)
defer closer.Close()
span, ctx := tracer.StartSpanFromContext(context.Background(), "some-operation")
defer span.Finish()
wantSpanContext := span.Context()
if fmt.Sprint(wantSpanContext) == "" {
t.Fatal("got empty start span context")
}
gotSpanContext := tracing.FromContext(ctx)
if fmt.Sprint(gotSpanContext) == "" {
t.Fatal("got empty span context")
}
if fmt.Sprint(gotSpanContext) != fmt.Sprint(wantSpanContext) {
t.Errorf("got span context %+v, want %+v", gotSpanContext, wantSpanContext)
}
}
func TestWithContext(t *testing.T) {
tracer, closer := newTracer(t)
defer closer.Close()
span, _ := tracer.StartSpanFromContext(context.Background(), "some-operation")
defer span.Finish()
wantSpanContext := span.Context()
if fmt.Sprint(wantSpanContext) == "" {
t.Fatal("got empty start span context")
}
ctx := tracing.WithContext(context.Background(), span.Context())
gotSpanContext := tracing.FromContext(ctx)
if fmt.Sprint(gotSpanContext) == "" {
t.Fatal("got empty span context")
}
if fmt.Sprint(gotSpanContext) != fmt.Sprint(wantSpanContext) {
t.Errorf("got span context %+v, want %+v", gotSpanContext, wantSpanContext)
}
}
func newTracer(t *testing.T) (*tracing.Tracer, io.Closer) {
t.Helper()
tracer, closer, err := tracing.NewTracer(&tracing.Options{
Enabled: true,
ServiceName: "test",
})
if err != nil {
t.Fatal(err)
}
return tracer, closer
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment