From 2669004ec29ef239e88e8e47c3530c374e2e13c8 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Wed, 22 Jan 2020 21:09:10 +0530 Subject: [PATCH 01/13] introspector in swarm --- swarm.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/swarm.go b/swarm.go index f7c57717..807c9865 100644 --- a/swarm.go +++ b/swarm.go @@ -9,6 +9,7 @@ import ( "sync/atomic" "time" + coreit "github.com/libp2p/go-libp2p-core/introspection" "github.com/libp2p/go-libp2p-core/metrics" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" @@ -97,7 +98,7 @@ type Swarm struct { } // NewSwarm constructs a Swarm -func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc metrics.Reporter) *Swarm { +func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc metrics.Reporter, introspector coreit.IntrospectorRegistry) *Swarm { s := &Swarm{ local: local, peers: peers, @@ -115,6 +116,13 @@ func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc s.proc = goprocessctx.WithContextAndTeardown(ctx, s.teardown) s.ctx = goprocessctx.OnClosingContext(s.proc) + // TODO register provider for introspection + if introspector != nil { + if err := introspector.RegisterProviders(&coreit.ProvidersTree{Conn: &coreit.ConnProviders{}, Stream: &coreit.StreamProviders{}}); err != nil { + log.Errorf("swarm failed to register itself as a provider with the introspector, err=%s", err) + } + } + return s } From bdf15ec9958afc0d152d513c329551d840dd4da4 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Sat, 25 Jan 2020 01:11:36 +0530 Subject: [PATCH 02/13] introspector for swarm --- go.mod | 2 + go.sum | 5 ++ introspection.go | 146 +++++++++++++++++++++++++++++++++++++++++++++++ swarm.go | 17 ++++-- swarm_conn.go | 10 ++++ swarm_stream.go | 3 + 6 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 introspection.go diff --git a/go.mod b/go.mod index 88fee581..4dd2082e 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,8 @@ require ( github.com/multiformats/go-multiaddr v0.2.0 github.com/multiformats/go-multiaddr-fmt v0.1.0 github.com/multiformats/go-multiaddr-net v0.1.1 + github.com/pkg/errors v0.8.1 + github.com/satori/go.uuid v1.2.0 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 ) diff --git a/go.sum b/go.sum index 021283d8..f226e949 100644 --- a/go.sum +++ b/go.sum @@ -103,6 +103,7 @@ github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-flow-metrics v0.0.2 h1:U5TvqfoyR6GVRM+bC15Ux1ltar1kbj6Zw6xOVR02CZs= github.com/libp2p/go-flow-metrics v0.0.2/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= @@ -115,6 +116,7 @@ github.com/libp2p/go-libp2p-core v0.2.4 h1:Et6ykkTwI6PU44tr8qUF9k43vP0aduMNniShA github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= github.com/libp2p/go-libp2p-core v0.2.5 h1:iP1PIiIrlRrGbE1fYq2918yBc5NlCH3pFuIPSWU9hds= github.com/libp2p/go-libp2p-core v0.2.5/go.mod h1:6+5zJmKhsf7yHn1RbmYDu08qDUpIUxGdqHuEZckmZOA= +github.com/libp2p/go-libp2p-core v0.3.0 h1:F7PqduvrztDtFsAa/bcheQ3azmNo+Nq7m8hQY5GiUW8= github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= @@ -239,6 +241,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smola/gocompat v0.2.0 h1:6b1oIMlUXIpz//VKEDzPVBK8KG7beVwmHIUEBIs/Pns= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= @@ -273,6 +277,7 @@ github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7V github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/introspection.go b/introspection.go new file mode 100644 index 00000000..8b8d5add --- /dev/null +++ b/introspection.go @@ -0,0 +1,146 @@ +package swarm + +import ( + "github.com/libp2p/go-libp2p-core/introspect" + "github.com/libp2p/go-libp2p-core/network" + "github.com/pkg/errors" +) + +func (swarm *Swarm) toIntrospectConnectionsPb(query introspect.ConnectionQueryInput) ([]*introspect.Connection, error) { + swarm.conns.RLock() + defer swarm.conns.RUnlock() + + containsId := func(ids []introspect.ConnID, id string) bool { + for _, i := range ids { + if string(i) == id { + return true + } + } + return false + } + + var iconns []*introspect.Connection + + for _, conns := range swarm.conns.m { + for _, c := range conns { + switch query.Type { + case introspect.ConnListQueryTypeForIds: + if containsId(query.ConnIDs, c.id) { + ic, err := swarm.toIntrospectConnectionPb(query, c) + if err != nil { + return nil, errors.Wrap(err, "failed to convert connection to introspect.Connection") + } + iconns = append(iconns, ic) + } + case introspect.ConnListQueryTypeAll: + ic, err := swarm.toIntrospectConnectionPb(query, c) + if err != nil { + return nil, errors.Wrap(err, "failed to convert connection to introspect.Connection") + } + iconns = append(iconns, ic) + } + } + } + return iconns, nil +} + +func (swarm *Swarm) toIntrospectConnectionPb(query introspect.ConnectionQueryInput, c *Conn) (*introspect.Connection, error) { + c.streams.Lock() + defer c.streams.Unlock() + + ic := &introspect.Connection{} + ic.Id = c.id + ic.PeerId = c.RemotePeer().String() + + ic.Endpoints = &introspect.EndpointPair{SrcMultiaddr: c.LocalMultiaddr().String(), DstMultiaddr: c.RemoteMultiaddr().String()} + + switch c.stat.Direction { + case network.DirInbound: + ic.Role = introspect.Role_RESPONDER + case network.DirOutbound: + ic.Role = introspect.Role_INITIATOR + } + + sl := &introspect.StreamList{} + for s, _ := range c.streams.m { + switch query.StreamOutputType { + case introspect.QueryOutputTypeFull: + isl, err := swarm.toIntrospectStreamPb(s, ic) + if err != nil { + return nil, errors.Wrap(err, "failed to convert swarm stream to introspect.Stream") + } + sl.Streams = append(sl.Streams, isl) + case introspect.QueryOutputTypeIds: + sl.StreamIds = append(sl.StreamIds, []byte(s.id)) + } + } + ic.Streams = sl + + // TODO How ? + ic.Timeline = &introspect.Connection_Timeline{} + + // TODO How ? + ic.Traffic = &introspect.Traffic{} + + // TODO How ? + ic.Attribs = &introspect.Connection_Attributes{} + + // TODO How do we track other states ? + ic.Status = introspect.Status_ACTIVE + + // TODO What's this ? + ic.TransportId = nil + + // TODO What's this ? + ic.UserProvidedTags = []string{""} + + // TODO How ? + ic.LatencyNs = 0 + + // TODO How ? + //ic.RelayedOver + + return ic, nil +} + +func (swarm *Swarm) toIntrospectStreamPb(s *Stream, ic *introspect.Connection) (*introspect.Stream, error) { + is := &introspect.Stream{} + is.Id = s.id + is.Protocol = string(s.Protocol()) + + switch s.stat.Direction { + case network.DirInbound: + is.Role = introspect.Role_RESPONDER + case network.DirOutbound: + is.Role = introspect.Role_INITIATOR + } + + is.Conn = &introspect.Stream_ConnectionRef{Connection: &introspect.Stream_ConnectionRef_Conn{ic}} + + s.state.Lock() + defer s.state.Unlock() + switch s.state.v { + case streamOpen: + is.Status = introspect.Status_ACTIVE + case streamReset: + is.Status = introspect.Status_ERROR + case streamCloseBoth: + is.Status = introspect.Status_CLOSED + default: + is.Status = introspect.Status_ACTIVE + } + + // TODO How ? + is.Timeline = &introspect.Stream_Timeline{} + + // TODO How ? + is.Traffic = &introspect.Traffic{} + + // TODO How ? + is.LatencyNs = 0 + + // TODO What's this ? + is.UserProvidedTags = []string{""} + + return is, nil +} diff --git a/swarm.go b/swarm.go index 807c9865..f331962f 100644 --- a/swarm.go +++ b/swarm.go @@ -4,12 +4,13 @@ import ( "context" "errors" "fmt" + "strings" "sync" "sync/atomic" "time" - coreit "github.com/libp2p/go-libp2p-core/introspection" + "github.com/libp2p/go-libp2p-core/introspect" "github.com/libp2p/go-libp2p-core/metrics" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" @@ -22,6 +23,8 @@ import ( filter "github.com/libp2p/go-maddr-filter" ma "github.com/multiformats/go-multiaddr" + pkgerr "github.com/pkg/errors" + uuid "github.com/satori/go.uuid" mafilter "github.com/whyrusleeping/multiaddr-filter" ) @@ -98,7 +101,7 @@ type Swarm struct { } // NewSwarm constructs a Swarm -func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc metrics.Reporter, introspector coreit.IntrospectorRegistry) *Swarm { +func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc metrics.Reporter, introspector introspect.Introspector) *Swarm { s := &Swarm{ local: local, peers: peers, @@ -116,9 +119,10 @@ func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc s.proc = goprocessctx.WithContextAndTeardown(ctx, s.teardown) s.ctx = goprocessctx.OnClosingContext(s.proc) - // TODO register provider for introspection if introspector != nil { - if err := introspector.RegisterProviders(&coreit.ProvidersTree{Conn: &coreit.ConnProviders{}, Stream: &coreit.StreamProviders{}}); err != nil { + if err := introspector.RegisterProviders(&introspect.ProvidersMap{ + Connection: s.toIntrospectConnectionsPb, + }); err != nil { log.Errorf("swarm failed to register itself as a provider with the introspector, err=%s", err) } } @@ -217,11 +221,16 @@ func (s *Swarm) addConn(tc transport.CapableConn, dir network.Direction) (*Conn, } // Wrap and register the connection. + id, err := uuid.NewV4() + if err != nil { + return nil, pkgerr.Wrap(err, "failed to generate connection uuid") + } stat := network.Stat{Direction: dir} c := &Conn{ conn: tc, swarm: s, stat: stat, + id: id.String(), } c.streams.m = make(map[*Stream]struct{}) s.conns.m[p] = append(s.conns.m[p], c) diff --git a/swarm_conn.go b/swarm_conn.go index c09957c1..b9c74fc7 100644 --- a/swarm_conn.go +++ b/swarm_conn.go @@ -5,6 +5,8 @@ import ( "fmt" "sync" + pkgerr "github.com/pkg/errors" + ic "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/mux" "github.com/libp2p/go-libp2p-core/network" @@ -12,6 +14,7 @@ import ( "github.com/libp2p/go-libp2p-core/transport" ma "github.com/multiformats/go-multiaddr" + uuid "github.com/satori/go.uuid" ) // TODO: Put this elsewhere. @@ -22,6 +25,7 @@ var ErrConnClosed = errors.New("connection closed") // Conn is the connection type used by swarm. In general, you won't use this // type directly. type Conn struct { + id string conn transport.CapableConn swarm *Swarm @@ -185,11 +189,17 @@ func (c *Conn) addStream(ts mux.MuxedStream, dir network.Direction) (*Stream, er } // Wrap and register the stream. + id, err := uuid.NewV4() + if err != nil { + pkgerr.Wrap(err, "failed to generate uuid for stream") + } stat := network.Stat{Direction: dir} s := &Stream{ stream: ts, conn: c, stat: stat, + id: id.String(), + connId: c.id, } c.streams.m[s] = struct{}{} diff --git a/swarm_stream.go b/swarm_stream.go index 9dded2a9..e42cd2de 100644 --- a/swarm_stream.go +++ b/swarm_stream.go @@ -28,6 +28,9 @@ var _ network.Stream = &Stream{} // Stream is the stream type used by swarm. In general, you won't use this type // directly. type Stream struct { + id string + connId string + stream mux.MuxedStream conn *Conn From 875019ae7903224695ef8cdbdcc7369dc79dbabc Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 27 Jan 2020 18:48:34 +0530 Subject: [PATCH 03/13] Swarm introspection --- conn_introspect.go | 106 +++++++++++++++++++++++++++++++ go.mod | 2 + go.sum | 3 + introspect.go | 94 ++++++++++++++++++++++++++++ introspect_test.go | 90 ++++++++++++++++++++++++++ introspection.go | 146 ------------------------------------------- stream_introspect.go | 73 ++++++++++++++++++++++ swarm.go | 8 +-- swarm_conn.go | 11 ++-- swarm_stream.go | 5 +- testing/testing.go | 2 +- 11 files changed, 379 insertions(+), 161 deletions(-) create mode 100644 conn_introspect.go create mode 100644 introspect.go create mode 100644 introspect_test.go delete mode 100644 introspection.go create mode 100644 stream_introspect.go diff --git a/conn_introspect.go b/conn_introspect.go new file mode 100644 index 00000000..1d80b91e --- /dev/null +++ b/conn_introspect.go @@ -0,0 +1,106 @@ +package swarm + +import ( + "github.com/libp2p/go-libp2p-core/introspect" + "github.com/libp2p/go-libp2p-core/network" + "github.com/pkg/errors" +) + +type connIntrospector struct { + c *Conn + s *Swarm + query *introspect.ConnectionQueryInput +} + +func (ci *connIntrospector) id() string { + return ci.c.id +} + +func (ci *connIntrospector) remotePeerId() string { + return ci.c.RemotePeer().String() +} + +func (ci *connIntrospector) endPoints() *introspect.EndpointPair { + return &introspect.EndpointPair{SrcMultiaddr: ci.c.LocalMultiaddr().String(), DstMultiaddr: ci.c.RemoteMultiaddr().String()} +} + +func (ci *connIntrospector) role() introspect.Role { + if ci.c.stat.Direction == network.DirInbound { + return introspect.Role_RESPONDER + } else { + return introspect.Role_INITIATOR + } +} + +// TODO Number of packets & instantaneous bandwidth ? +// Should we have a separate "flow-metre" for a connection to prepare for a message oriented world ? +func (ci *connIntrospector) traffic() *introspect.Traffic { + if ci.s.bwc != nil { + t := &introspect.Traffic{} + t.TrafficIn = &introspect.DataGauge{} + t.TrafficOut = &introspect.DataGauge{} + for s, _ := range ci.c.streams.m { + streamMetrics := ci.s.bwc.GetBandwidthForProtocol(s.Protocol()) + t.TrafficIn.CumBytes = t.TrafficIn.CumBytes + uint64(streamMetrics.TotalIn) + t.TrafficIn.InstBw = t.TrafficIn.InstBw + uint64(streamMetrics.RateIn) + + t.TrafficOut.CumBytes = t.TrafficOut.CumBytes + uint64(streamMetrics.TotalOut) + t.TrafficOut.InstBw = t.TrafficOut.CumBytes + uint64(streamMetrics.RateOut) + } + return t + } + + return nil +} + +func (ci *connIntrospector) streams() (*introspect.StreamList, error) { + sl := &introspect.StreamList{} + for s, _ := range ci.c.streams.m { + switch ci.query.StreamOutputType { + case introspect.QueryOutputTypeFull: + isl, err := ci.s.introspectStream(s, ci.c) + if err != nil { + return nil, errors.Wrap(err, "failed to convert swarm stream to introspect.Stream") + } + sl.Streams = append(sl.Streams, isl) + case introspect.QueryOutputTypeIds: + sl.StreamIds = append(sl.StreamIds, []byte(s.id)) + } + } + return sl, nil +} + +// TODO Where do we get this information from ? +func (ci *connIntrospector) attribs() *introspect.Connection_Attributes { + return nil +} + +// TODO Where are the hook points and where do we persist closed time ? +func (ci *connIntrospector) timeline() *introspect.Connection_Timeline { + return nil +} + +// TODO How do we track othe states ? +func (ci *connIntrospector) status() introspect.Status { + return introspect.Status_ACTIVE +} + +// TODO What's this & how to fetch it ? +func (ci *connIntrospector) transportId() []byte { + return nil +} + +// TODO How ? +func (ci *connIntrospector) latencyNs() uint64 { + return 0 +} + +// TODO What's this ? +func (ci *connIntrospector) userProvidedTags() []string { + return nil +} + +// TODO What's this & how to fetch it ? +func (ci *connIntrospector) relayedOver() *introspect.Connection_Conn { + return nil +} diff --git a/go.mod b/go.mod index 4dd2082e..32c53009 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/libp2p/go-libp2p-swarm require ( + github.com/golang/protobuf v1.3.2 github.com/ipfs/go-log v0.0.1 github.com/jbenet/goprocess v0.1.3 github.com/libp2p/go-addr-util v0.0.1 @@ -20,6 +21,7 @@ require ( github.com/multiformats/go-multiaddr-net v0.1.1 github.com/pkg/errors v0.8.1 github.com/satori/go.uuid v1.2.0 + github.com/stretchr/testify v1.4.0 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 ) diff --git a/go.sum b/go.sum index f226e949..d1ef7d3e 100644 --- a/go.sum +++ b/go.sum @@ -46,6 +46,8 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -264,6 +266,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= diff --git a/introspect.go b/introspect.go new file mode 100644 index 00000000..f8ad4877 --- /dev/null +++ b/introspect.go @@ -0,0 +1,94 @@ +package swarm + +import ( + "github.com/libp2p/go-libp2p-core/introspect" + "github.com/pkg/errors" +) + +// IntrospectConns introspects & returns the swarm connections +func (swarm *Swarm) IntrospectConns(query introspect.ConnectionQueryInput) ([]*introspect.Connection, error) { + swarm.conns.RLock() + defer swarm.conns.RUnlock() + + containsId := func(ids []introspect.ConnID, id string) bool { + for _, i := range ids { + if string(i) == id { + return true + } + } + return false + } + + var iconns []*introspect.Connection + + // iterate over all connections the swarm has & resolve the ones required by the query + for _, conns := range swarm.conns.m { + for _, c := range conns { + switch query.Type { + case introspect.ConnListQueryTypeForIds: + if containsId(query.ConnIDs, c.id) { + ic, err := swarm.introspectConnection(&query, c) + if err != nil { + return nil, errors.Wrap(err, "failed to convert connection to introspect.Connection") + } + iconns = append(iconns, ic) + } + case introspect.ConnListQueryTypeAll: + ic, err := swarm.introspectConnection(&query, c) + if err != nil { + return nil, errors.Wrap(err, "failed to convert connection to introspect.Connection") + } + iconns = append(iconns, ic) + } + } + } + return iconns, nil +} + +func (swarm *Swarm) introspectConnection(query *introspect.ConnectionQueryInput, c *Conn) (*introspect.Connection, error) { + c.streams.Lock() + defer c.streams.Unlock() + + ci := &connIntrospector{c, swarm, query} + ic := &introspect.Connection{} + + ic.Id = ci.id() + ic.PeerId = ci.remotePeerId() + ic.Endpoints = ci.endPoints() + ic.Role = ci.role() + + streams, err := ci.streams() + if err != nil { + return nil, errors.Wrap(err, "failed to introspect stream for connection") + } + ic.Streams = streams + + ic.Traffic = ci.traffic() + ic.Timeline = ci.timeline() + ic.Attribs = ci.attribs() + ic.Status = ci.status() + ic.TransportId = ci.transportId() + ic.UserProvidedTags = ci.userProvidedTags() + ic.LatencyNs = ci.latencyNs() + ic.RelayedOver = ci.relayedOver() + + return ic, nil +} + +func (swarm *Swarm) introspectStream(s *Stream, c *Conn) (*introspect.Stream, error) { + s.state.Lock() + defer s.state.Unlock() + + si := &streamIntrospector{s, c} + is := &introspect.Stream{} + is.Id = si.id() + is.Protocol = si.protocol() + is.Role = si.role() + is.Status = si.status() + is.Conn = si.conn() + is.Traffic = si.traffic() + is.Timeline = si.timeline() + is.LatencyNs = si.latency() + is.UserProvidedTags = si.userProvidedTags() + return is, nil +} diff --git a/introspect_test.go b/introspect_test.go new file mode 100644 index 00000000..b36b0160 --- /dev/null +++ b/introspect_test.go @@ -0,0 +1,90 @@ +package swarm_test + +import ( + "context" + "github.com/libp2p/go-libp2p-core/introspect" + "github.com/libp2p/go-libp2p-core/protocol" + swarm "github.com/libp2p/go-libp2p-swarm" + "github.com/stretchr/testify/require" + "testing" +) + +func TestConnsAndStreamIntrospect(t *testing.T) { + ctx := context.Background() + swarms := makeSwarms(ctx, t, 2) + connectSwarms(t, ctx, []*swarm.Swarm{swarms[0], swarms[1]}) + + // ----- Swarm 1 opens TWO streams to Swarm 2 + pid1 := protocol.ID("1") + pid2 := protocol.ID("2") + s1, err := swarms[0].NewStream(ctx, swarms[1].LocalPeer()) + s1.SetProtocol(pid1) + require.NoError(t, err) + s2, err := swarms[0].NewStream(ctx, swarms[1].LocalPeer()) + require.NoError(t, err) + s2.SetProtocol(pid2) + + // send 4 bytes on stream 1 & 5 bytes on stream 2 + msg1 := "abcd" + msg2 := "12345" + s1.Write([]byte(msg1)) + s2.Write([]byte(msg2)) + // wait for the metres to kick in + for { + cis, err := swarms[0].IntrospectConns(introspect.ConnectionQueryInput{Type: introspect.ConnListQueryTypeAll, + StreamOutputType: introspect.QueryOutputTypeFull}) + require.NoError(t, err) + if cis[0].Traffic.TrafficOut.CumBytes != 0 { + break + } + } + + // ----- Introspect Swarm 1 + cis, err := swarms[0].IntrospectConns(introspect.ConnectionQueryInput{Type: introspect.ConnListQueryTypeAll, + StreamOutputType: introspect.QueryOutputTypeFull}) + + // connection checks + require.Len(t, cis, 1) + require.Len(t, cis[0].Streams.Streams, 2) + require.NotEmpty(t, cis[0].Id) + require.Equal(t, swarms[1].LocalPeer().String(), cis[0].PeerId) + require.Equal(t, introspect.Status_ACTIVE, cis[0].Status) + require.Equal(t, introspect.Role_INITIATOR, cis[0].Role) + require.Equal(t, swarms[0].Conns()[0].LocalMultiaddr().String(), cis[0].Endpoints.SrcMultiaddr) + require.Equal(t, swarms[0].Conns()[0].RemoteMultiaddr().String(), cis[0].Endpoints.DstMultiaddr) + require.True(t, int(cis[0].Traffic.TrafficOut.CumBytes) == len(msg1)+len(msg2)) + + // map stream to protocols + protocolToStream := make(map[string]*introspect.Stream) + for _, s := range cis[0].Streams.Streams { + protocolToStream[s.Protocol] = s + } + + // introspect stream 1 + stream1 := protocolToStream["1"] + require.NotEmpty(t, stream1) + require.Equal(t, "1", stream1.Protocol) + require.Equal(t, introspect.Role_INITIATOR, stream1.Role) + require.Equal(t, introspect.Status_ACTIVE, stream1.Status) + require.NotEmpty(t, stream1.Id) + require.True(t, len(msg1) == int(stream1.Traffic.TrafficOut.CumBytes)) + require.True(t, 0 == int(stream1.Traffic.TrafficIn.CumBytes)) + + // introspect stream 2 + stream2 := protocolToStream["2"] + require.NotEmpty(t, stream2) + require.Equal(t, "2", stream2.Protocol) + require.Equal(t, introspect.Role_INITIATOR, stream2.Role) + require.Equal(t, introspect.Status_ACTIVE, stream2.Status) + require.NotEmpty(t, stream2.Id) + require.NotEqual(t, stream2.Id, stream1.Id) + require.True(t, len(msg2) == int(stream2.Traffic.TrafficOut.CumBytes)) + require.True(t, 0 == int(stream2.Traffic.TrafficIn.CumBytes)) + + // reset stream 1 & verify + require.NoError(t, s1.Reset()) + cis, err = swarms[0].IntrospectConns(introspect.ConnectionQueryInput{Type: introspect.ConnListQueryTypeAll, + StreamOutputType: introspect.QueryOutputTypeFull}) + require.NoError(t, err) + require.Len(t, cis[0].Streams.Streams, 1) +} diff --git a/introspection.go b/introspection.go deleted file mode 100644 index 8b8d5add..00000000 --- a/introspection.go +++ /dev/null @@ -1,146 +0,0 @@ -package swarm - -import ( - "github.com/libp2p/go-libp2p-core/introspect" - "github.com/libp2p/go-libp2p-core/network" - "github.com/pkg/errors" -) - -func (swarm *Swarm) toIntrospectConnectionsPb(query introspect.ConnectionQueryInput) ([]*introspect.Connection, error) { - swarm.conns.RLock() - defer swarm.conns.RUnlock() - - containsId := func(ids []introspect.ConnID, id string) bool { - for _, i := range ids { - if string(i) == id { - return true - } - } - return false - } - - var iconns []*introspect.Connection - - for _, conns := range swarm.conns.m { - for _, c := range conns { - switch query.Type { - case introspect.ConnListQueryTypeForIds: - if containsId(query.ConnIDs, c.id) { - ic, err := swarm.toIntrospectConnectionPb(query, c) - if err != nil { - return nil, errors.Wrap(err, "failed to convert connection to introspect.Connection") - } - iconns = append(iconns, ic) - } - case introspect.ConnListQueryTypeAll: - ic, err := swarm.toIntrospectConnectionPb(query, c) - if err != nil { - return nil, errors.Wrap(err, "failed to convert connection to introspect.Connection") - } - iconns = append(iconns, ic) - } - } - } - return iconns, nil -} - -func (swarm *Swarm) toIntrospectConnectionPb(query introspect.ConnectionQueryInput, c *Conn) (*introspect.Connection, error) { - c.streams.Lock() - defer c.streams.Unlock() - - ic := &introspect.Connection{} - ic.Id = c.id - ic.PeerId = c.RemotePeer().String() - - ic.Endpoints = &introspect.EndpointPair{SrcMultiaddr: c.LocalMultiaddr().String(), DstMultiaddr: c.RemoteMultiaddr().String()} - - switch c.stat.Direction { - case network.DirInbound: - ic.Role = introspect.Role_RESPONDER - case network.DirOutbound: - ic.Role = introspect.Role_INITIATOR - } - - sl := &introspect.StreamList{} - for s, _ := range c.streams.m { - switch query.StreamOutputType { - case introspect.QueryOutputTypeFull: - isl, err := swarm.toIntrospectStreamPb(s, ic) - if err != nil { - return nil, errors.Wrap(err, "failed to convert swarm stream to introspect.Stream") - } - sl.Streams = append(sl.Streams, isl) - case introspect.QueryOutputTypeIds: - sl.StreamIds = append(sl.StreamIds, []byte(s.id)) - } - } - ic.Streams = sl - - // TODO How ? - ic.Timeline = &introspect.Connection_Timeline{} - - // TODO How ? - ic.Traffic = &introspect.Traffic{} - - // TODO How ? - ic.Attribs = &introspect.Connection_Attributes{} - - // TODO How do we track other states ? - ic.Status = introspect.Status_ACTIVE - - // TODO What's this ? - ic.TransportId = nil - - // TODO What's this ? - ic.UserProvidedTags = []string{""} - - // TODO How ? - ic.LatencyNs = 0 - - // TODO How ? - //ic.RelayedOver - - return ic, nil -} - -func (swarm *Swarm) toIntrospectStreamPb(s *Stream, ic *introspect.Connection) (*introspect.Stream, error) { - is := &introspect.Stream{} - is.Id = s.id - is.Protocol = string(s.Protocol()) - - switch s.stat.Direction { - case network.DirInbound: - is.Role = introspect.Role_RESPONDER - case network.DirOutbound: - is.Role = introspect.Role_INITIATOR - } - - is.Conn = &introspect.Stream_ConnectionRef{Connection: &introspect.Stream_ConnectionRef_Conn{ic}} - - s.state.Lock() - defer s.state.Unlock() - switch s.state.v { - case streamOpen: - is.Status = introspect.Status_ACTIVE - case streamReset: - is.Status = introspect.Status_ERROR - case streamCloseBoth: - is.Status = introspect.Status_CLOSED - default: - is.Status = introspect.Status_ACTIVE - } - - // TODO How ? - is.Timeline = &introspect.Stream_Timeline{} - - // TODO How ? - is.Traffic = &introspect.Traffic{} - - // TODO How ? - is.LatencyNs = 0 - - // TODO What's this ? - is.UserProvidedTags = []string{""} - - return is, nil -} diff --git a/stream_introspect.go b/stream_introspect.go new file mode 100644 index 00000000..6a64968f --- /dev/null +++ b/stream_introspect.go @@ -0,0 +1,73 @@ +package swarm + +import ( + "github.com/golang/protobuf/ptypes/timestamp" + "github.com/libp2p/go-libp2p-core/introspect" + "github.com/libp2p/go-libp2p-core/network" +) + +type streamIntrospector struct { + s *Stream + c *Conn +} + +func (si *streamIntrospector) id() string { + return si.s.id +} + +func (si *streamIntrospector) protocol() string { + return string(si.s.Protocol()) +} + +func (si *streamIntrospector) status() introspect.Status { + switch si.s.state.v { + case streamOpen: + return introspect.Status_ACTIVE + case streamReset: + return introspect.Status_ERROR + case streamCloseBoth: + return introspect.Status_CLOSED + default: + return introspect.Status_ACTIVE + } +} + +func (si *streamIntrospector) role() introspect.Role { + if si.s.stat.Direction == network.DirInbound { + return introspect.Role_RESPONDER + } else { + return introspect.Role_INITIATOR + } +} + +func (si *streamIntrospector) conn() *introspect.Stream_ConnectionRef { + return &introspect.Stream_ConnectionRef{Connection: &introspect.Stream_ConnectionRef_ConnId{si.c.id}} +} + +// TODO Number packets ? Is the RateIn/Out a good approximation here ? +func (si *streamIntrospector) traffic() *introspect.Traffic { + if si.c.swarm.bwc != nil { + streamMetrics := si.s.conn.swarm.bwc.GetBandwidthForProtocol(si.s.Protocol()) + t := &introspect.Traffic{} + t.TrafficIn = &introspect.DataGauge{CumBytes: uint64(streamMetrics.TotalIn), InstBw: uint64(streamMetrics.RateIn)} + t.TrafficOut = &introspect.DataGauge{CumBytes: uint64(streamMetrics.TotalOut), InstBw: uint64(streamMetrics.RateOut)} + return t + } + + return nil +} + +// TODO What about closed time ? +func (si *streamIntrospector) timeline() *introspect.Stream_Timeline { + return &introspect.Stream_Timeline{OpenTs: ×tamp.Timestamp{Seconds: si.s.openTime.Unix()}} +} + +// TODO How ? +func (si *streamIntrospector) latency() uint64 { + return 0 +} + +// TODO What's this ? +func (si *streamIntrospector) userProvidedTags() []string { + return nil +} diff --git a/swarm.go b/swarm.go index f331962f..33b2c68c 100644 --- a/swarm.go +++ b/swarm.go @@ -23,7 +23,6 @@ import ( filter "github.com/libp2p/go-maddr-filter" ma "github.com/multiformats/go-multiaddr" - pkgerr "github.com/pkg/errors" uuid "github.com/satori/go.uuid" mafilter "github.com/whyrusleeping/multiaddr-filter" ) @@ -121,7 +120,7 @@ func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc if introspector != nil { if err := introspector.RegisterProviders(&introspect.ProvidersMap{ - Connection: s.toIntrospectConnectionsPb, + Connection: s.IntrospectConns, }); err != nil { log.Errorf("swarm failed to register itself as a provider with the introspector, err=%s", err) } @@ -221,10 +220,7 @@ func (s *Swarm) addConn(tc transport.CapableConn, dir network.Direction) (*Conn, } // Wrap and register the connection. - id, err := uuid.NewV4() - if err != nil { - return nil, pkgerr.Wrap(err, "failed to generate connection uuid") - } + id := uuid.NewV4() stat := network.Stat{Direction: dir} c := &Conn{ conn: tc, diff --git a/swarm_conn.go b/swarm_conn.go index b9c74fc7..92d0df11 100644 --- a/swarm_conn.go +++ b/swarm_conn.go @@ -4,8 +4,7 @@ import ( "errors" "fmt" "sync" - - pkgerr "github.com/pkg/errors" + "time" ic "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/mux" @@ -173,6 +172,7 @@ func (c *Conn) Stat() network.Stat { // NewStream returns a new Stream from this connection func (c *Conn) NewStream() (network.Stream, error) { ts, err := c.conn.OpenStream() + if err != nil { return nil, err } @@ -189,10 +189,7 @@ func (c *Conn) addStream(ts mux.MuxedStream, dir network.Direction) (*Stream, er } // Wrap and register the stream. - id, err := uuid.NewV4() - if err != nil { - pkgerr.Wrap(err, "failed to generate uuid for stream") - } + id := uuid.NewV4() stat := network.Stat{Direction: dir} s := &Stream{ stream: ts, @@ -200,6 +197,8 @@ func (c *Conn) addStream(ts mux.MuxedStream, dir network.Direction) (*Stream, er stat: stat, id: id.String(), connId: c.id, + // TODO Is this good enough ? + openTime: time.Now(), } c.streams.m[s] = struct{}{} diff --git a/swarm_stream.go b/swarm_stream.go index e42cd2de..aa7a80c2 100644 --- a/swarm_stream.go +++ b/swarm_stream.go @@ -28,8 +28,9 @@ var _ network.Stream = &Stream{} // Stream is the stream type used by swarm. In general, you won't use this type // directly. type Stream struct { - id string - connId string + id string + connId string + openTime time.Time stream mux.MuxedStream conn *Conn diff --git a/testing/testing.go b/testing/testing.go index 5e396024..6fdf77f4 100644 --- a/testing/testing.go +++ b/testing/testing.go @@ -72,7 +72,7 @@ func GenSwarm(t *testing.T, ctx context.Context, opts ...Option) *swarm.Swarm { ps := pstoremem.NewPeerstore() ps.AddPubKey(p.ID, p.PubKey) ps.AddPrivKey(p.ID, p.PrivKey) - s := swarm.NewSwarm(ctx, p.ID, ps, metrics.NewBandwidthCounter()) + s := swarm.NewSwarm(ctx, p.ID, ps, metrics.NewBandwidthCounter(), nil) s.Process().AddChild(goprocess.WithTeardown(ps.Close)) tcpTransport := tcp.NewTCPTransport(GenUpgrader(s)) From 56ecada36e38e99db309b65066becbad49089b65 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Tue, 28 Jan 2020 17:11:24 +0530 Subject: [PATCH 04/13] modified test --- introspect_test.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/introspect_test.go b/introspect_test.go index b36b0160..94165998 100644 --- a/introspect_test.go +++ b/introspect_test.go @@ -87,4 +87,11 @@ func TestConnsAndStreamIntrospect(t *testing.T) { StreamOutputType: introspect.QueryOutputTypeFull}) require.NoError(t, err) require.Len(t, cis[0].Streams.Streams, 1) -} + + // test for stream Ids + cis, err = swarms[0].IntrospectConns(introspect.ConnectionQueryInput{Type: introspect.ConnListQueryTypeAll, + StreamOutputType: introspect.QueryOutputTypeIds}) + require.NoError(t, err) + require.Len(t, cis[0].Streams.Streams, 0) + require.Len(t, cis[0].Streams.StreamIds, 1) +} \ No newline at end of file From e2c54c7b4352ea0dc68ba4246757bc7614ad0dfb Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Tue, 28 Jan 2020 19:49:07 +0530 Subject: [PATCH 05/13] introspection tests --- introspect.go | 15 +++++++++++++++ introspect_test.go | 8 +++++++- swarm.go | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/introspect.go b/introspect.go index f8ad4877..7c539b78 100644 --- a/introspect.go +++ b/introspect.go @@ -5,6 +5,21 @@ import ( "github.com/pkg/errors" ) +// IntrospectTraffic introspects & returns the overall traffic for this peer +func (s *Swarm) IntrospectTraffic() (*introspect.Traffic, error) { + if s.bwc != nil { + t := &introspect.Traffic{} + metrics := s.bwc.GetBandwidthTotals() + + t.TrafficIn = &introspect.DataGauge{CumBytes: uint64(metrics.TotalIn), InstBw: uint64(metrics.RateIn)} + t.TrafficOut = &introspect.DataGauge{CumBytes: uint64(metrics.TotalOut), InstBw: uint64(metrics.RateOut)} + + return t, nil + } + + return nil, nil +} + // IntrospectConns introspects & returns the swarm connections func (swarm *Swarm) IntrospectConns(query introspect.ConnectionQueryInput) ([]*introspect.Connection, error) { swarm.conns.RLock() diff --git a/introspect_test.go b/introspect_test.go index 94165998..066928a1 100644 --- a/introspect_test.go +++ b/introspect_test.go @@ -94,4 +94,10 @@ func TestConnsAndStreamIntrospect(t *testing.T) { require.NoError(t, err) require.Len(t, cis[0].Streams.Streams, 0) require.Len(t, cis[0].Streams.StreamIds, 1) -} \ No newline at end of file + + // introspect traffic + tr, err := swarms[0].IntrospectTraffic() + require.NoError(t, err) + require.True(t, tr.TrafficOut.CumBytes == uint64(len(msg1)+len(msg2))) + require.True(t, tr.TrafficIn.CumBytes == 0) +} diff --git a/swarm.go b/swarm.go index 33b2c68c..6639e77d 100644 --- a/swarm.go +++ b/swarm.go @@ -121,6 +121,7 @@ func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc if introspector != nil { if err := introspector.RegisterProviders(&introspect.ProvidersMap{ Connection: s.IntrospectConns, + Traffic: s.IntrospectTraffic, }); err != nil { log.Errorf("swarm failed to register itself as a provider with the introspector, err=%s", err) } From f51a990cccb2f1a0b0a0d8caaff7758d461697c7 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Wed, 29 Jan 2020 21:47:59 +0530 Subject: [PATCH 06/13] fix tests --- introspect_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/introspect_test.go b/introspect_test.go index 066928a1..9a8c8408 100644 --- a/introspect_test.go +++ b/introspect_test.go @@ -27,8 +27,10 @@ func TestConnsAndStreamIntrospect(t *testing.T) { // send 4 bytes on stream 1 & 5 bytes on stream 2 msg1 := "abcd" msg2 := "12345" - s1.Write([]byte(msg1)) - s2.Write([]byte(msg2)) + _, err = s1.Write([]byte(msg1)) + require.NoError(t, err) + _, err = s2.Write([]byte(msg2)) + require.NoError(t, err) // wait for the metres to kick in for { cis, err := swarms[0].IntrospectConns(introspect.ConnectionQueryInput{Type: introspect.ConnListQueryTypeAll, From 360e97302ef4ea5dd22ca55f9c5257b7df2686f5 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Wed, 5 Feb 2020 18:21:41 +0530 Subject: [PATCH 07/13] introspection changes as per new contract --- conn_introspect.go | 51 ++++++++----------- introspect.go | 116 +++++++++++++++++++++++++++++++++---------- introspect_test.go | 68 +++++++++++++++++-------- stream_introspect.go | 41 ++++++++------- swarm.go | 5 +- 5 files changed, 179 insertions(+), 102 deletions(-) diff --git a/conn_introspect.go b/conn_introspect.go index 1d80b91e..a241e6ad 100644 --- a/conn_introspect.go +++ b/conn_introspect.go @@ -1,15 +1,13 @@ package swarm import ( - "github.com/libp2p/go-libp2p-core/introspect" + introspectpb "github.com/libp2p/go-libp2p-core/introspect/pb" "github.com/libp2p/go-libp2p-core/network" - "github.com/pkg/errors" ) type connIntrospector struct { - c *Conn - s *Swarm - query *introspect.ConnectionQueryInput + c *Conn + s *Swarm } func (ci *connIntrospector) id() string { @@ -20,25 +18,25 @@ func (ci *connIntrospector) remotePeerId() string { return ci.c.RemotePeer().String() } -func (ci *connIntrospector) endPoints() *introspect.EndpointPair { - return &introspect.EndpointPair{SrcMultiaddr: ci.c.LocalMultiaddr().String(), DstMultiaddr: ci.c.RemoteMultiaddr().String()} +func (ci *connIntrospector) endPoints() *introspectpb.EndpointPair { + return &introspectpb.EndpointPair{SrcMultiaddr: ci.c.LocalMultiaddr().String(), DstMultiaddr: ci.c.RemoteMultiaddr().String()} } -func (ci *connIntrospector) role() introspect.Role { +func (ci *connIntrospector) role() introspectpb.Role { if ci.c.stat.Direction == network.DirInbound { - return introspect.Role_RESPONDER + return introspectpb.Role_RESPONDER } else { - return introspect.Role_INITIATOR + return introspectpb.Role_INITIATOR } } // TODO Number of packets & instantaneous bandwidth ? // Should we have a separate "flow-metre" for a connection to prepare for a message oriented world ? -func (ci *connIntrospector) traffic() *introspect.Traffic { +func (ci *connIntrospector) traffic() *introspectpb.Traffic { if ci.s.bwc != nil { - t := &introspect.Traffic{} - t.TrafficIn = &introspect.DataGauge{} - t.TrafficOut = &introspect.DataGauge{} + t := &introspectpb.Traffic{} + t.TrafficIn = &introspectpb.DataGauge{} + t.TrafficOut = &introspectpb.DataGauge{} for s, _ := range ci.c.streams.m { streamMetrics := ci.s.bwc.GetBandwidthForProtocol(s.Protocol()) t.TrafficIn.CumBytes = t.TrafficIn.CumBytes + uint64(streamMetrics.TotalIn) @@ -53,36 +51,27 @@ func (ci *connIntrospector) traffic() *introspect.Traffic { return nil } -func (ci *connIntrospector) streams() (*introspect.StreamList, error) { - sl := &introspect.StreamList{} +func (ci *connIntrospector) streams() (*introspectpb.StreamList, error) { + sl := &introspectpb.StreamList{} for s, _ := range ci.c.streams.m { - switch ci.query.StreamOutputType { - case introspect.QueryOutputTypeFull: - isl, err := ci.s.introspectStream(s, ci.c) - if err != nil { - return nil, errors.Wrap(err, "failed to convert swarm stream to introspect.Stream") - } - sl.Streams = append(sl.Streams, isl) - case introspect.QueryOutputTypeIds: - sl.StreamIds = append(sl.StreamIds, []byte(s.id)) - } + sl.StreamIds = append(sl.StreamIds, []byte(s.id)) } return sl, nil } // TODO Where do we get this information from ? -func (ci *connIntrospector) attribs() *introspect.Connection_Attributes { +func (ci *connIntrospector) attribs() *introspectpb.Connection_Attributes { return nil } // TODO Where are the hook points and where do we persist closed time ? -func (ci *connIntrospector) timeline() *introspect.Connection_Timeline { +func (ci *connIntrospector) timeline() *introspectpb.Connection_Timeline { return nil } // TODO How do we track othe states ? -func (ci *connIntrospector) status() introspect.Status { - return introspect.Status_ACTIVE +func (ci *connIntrospector) status() introspectpb.Status { + return introspectpb.Status_ACTIVE } // TODO What's this & how to fetch it ? @@ -101,6 +90,6 @@ func (ci *connIntrospector) userProvidedTags() []string { } // TODO What's this & how to fetch it ? -func (ci *connIntrospector) relayedOver() *introspect.Connection_Conn { +func (ci *connIntrospector) relayedOver() *introspectpb.Connection_Conn { return nil } diff --git a/introspect.go b/introspect.go index 7c539b78..c14a1ca6 100644 --- a/introspect.go +++ b/introspect.go @@ -2,17 +2,18 @@ package swarm import ( "github.com/libp2p/go-libp2p-core/introspect" + introspectpb "github.com/libp2p/go-libp2p-core/introspect/pb" "github.com/pkg/errors" ) // IntrospectTraffic introspects & returns the overall traffic for this peer -func (s *Swarm) IntrospectTraffic() (*introspect.Traffic, error) { +func (s *Swarm) IntrospectTraffic() (*introspectpb.Traffic, error) { if s.bwc != nil { - t := &introspect.Traffic{} + t := &introspectpb.Traffic{} metrics := s.bwc.GetBandwidthTotals() - t.TrafficIn = &introspect.DataGauge{CumBytes: uint64(metrics.TotalIn), InstBw: uint64(metrics.RateIn)} - t.TrafficOut = &introspect.DataGauge{CumBytes: uint64(metrics.TotalOut), InstBw: uint64(metrics.RateOut)} + t.TrafficIn = &introspectpb.DataGauge{CumBytes: uint64(metrics.TotalIn), InstBw: uint64(metrics.RateIn)} + t.TrafficOut = &introspectpb.DataGauge{CumBytes: uint64(metrics.TotalOut), InstBw: uint64(metrics.RateOut)} return t, nil } @@ -20,12 +21,12 @@ func (s *Swarm) IntrospectTraffic() (*introspect.Traffic, error) { return nil, nil } -// IntrospectConns introspects & returns the swarm connections -func (swarm *Swarm) IntrospectConns(query introspect.ConnectionQueryInput) ([]*introspect.Connection, error) { +// IntrospectConnections introspects & returns the swarm connections +func (swarm *Swarm) IntrospectConnections(query introspect.ConnectionQueryParams) ([]*introspectpb.Connection, error) { swarm.conns.RLock() defer swarm.conns.RUnlock() - containsId := func(ids []introspect.ConnID, id string) bool { + containsId := func(ids []introspect.ConnectionID, id string) bool { for _, i := range ids { if string(i) == id { return true @@ -34,38 +35,46 @@ func (swarm *Swarm) IntrospectConns(query introspect.ConnectionQueryInput) ([]*i return false } - var iconns []*introspect.Connection + var iconns []*introspectpb.Connection + + appendConnection := func(c *Conn) error { + if query.Output == introspect.QueryOutputFull { + ic, err := swarm.introspectConnection(c) + if err != nil { + return errors.Wrap(err, "failed to convert connection to introspect.Connection") + } + iconns = append(iconns, ic) + } else { + iconns = append(iconns, &introspectpb.Connection{Id: c.id}) + } + return nil + } // iterate over all connections the swarm has & resolve the ones required by the query for _, conns := range swarm.conns.m { for _, c := range conns { - switch query.Type { - case introspect.ConnListQueryTypeForIds: - if containsId(query.ConnIDs, c.id) { - ic, err := swarm.introspectConnection(&query, c) - if err != nil { - return nil, errors.Wrap(err, "failed to convert connection to introspect.Connection") + if query.Include != nil { + if containsId(query.Include, c.id) { + if err := appendConnection(c); err != nil { + return nil, err } - iconns = append(iconns, ic) } - case introspect.ConnListQueryTypeAll: - ic, err := swarm.introspectConnection(&query, c) - if err != nil { - return nil, errors.Wrap(err, "failed to convert connection to introspect.Connection") + } else { + if err := appendConnection(c); err != nil { + return nil, err } - iconns = append(iconns, ic) } } } return iconns, nil } -func (swarm *Swarm) introspectConnection(query *introspect.ConnectionQueryInput, c *Conn) (*introspect.Connection, error) { +func (swarm *Swarm) introspectConnection(c *Conn) (*introspectpb.Connection, error) { c.streams.Lock() defer c.streams.Unlock() - ci := &connIntrospector{c, swarm, query} - ic := &introspect.Connection{} + ci := &connIntrospector{c, swarm} + ic := &introspectpb.Connection{} ic.Id = ci.id() ic.PeerId = ci.remotePeerId() @@ -88,14 +97,69 @@ func (swarm *Swarm) introspectConnection(query *introspect.ConnectionQueryInput, ic.RelayedOver = ci.relayedOver() return ic, nil + +} + +func (swarm *Swarm) IntrospectStreams(query introspect.StreamQueryParams) (*introspectpb.StreamList, error) { + swarm.conns.RLock() + defer swarm.conns.RUnlock() + + containsId := func(ids []introspect.StreamID, id string) bool { + for _, i := range ids { + if string(i) == id { + return true + } + } + return false + } + + sl := &introspectpb.StreamList{} + + appendStream := func(s *Stream) error { + if query.Output == introspect.QueryOutputFull { + is, err := swarm.introspectStream(s) + if err != nil { + return errors.Wrap(err, "failed to convert stream to introspect.Stream") + } + sl.Streams = append(sl.Streams, is) + } else { + sl.StreamIds = append(sl.StreamIds, []byte(s.id)) + } + return nil + } + + // iterate over all connections the swarm has & resolve the streams in the connections required by the query + for _, conns := range swarm.conns.m { + for _, c := range conns { + // range over all streams in the connection + c.streams.Lock() + defer c.streams.Unlock() + + for s, _ := range c.streams.m { + if query.Include != nil { + if containsId(query.Include, s.id) { + if err := appendStream(s); err != nil { + return nil, err + } + } + } else { + if err := appendStream(s); err != nil { + return nil, err + } + } + } + + } + } + return sl, nil } -func (swarm *Swarm) introspectStream(s *Stream, c *Conn) (*introspect.Stream, error) { +func (swarm *Swarm) introspectStream(s *Stream) (*introspectpb.Stream, error) { s.state.Lock() defer s.state.Unlock() - si := &streamIntrospector{s, c} - is := &introspect.Stream{} + si := &streamIntrospector{swarm, s} + is := &introspectpb.Stream{} is.Id = si.id() is.Protocol = si.protocol() is.Role = si.role() diff --git a/introspect_test.go b/introspect_test.go index 9a8c8408..abee5ffc 100644 --- a/introspect_test.go +++ b/introspect_test.go @@ -3,6 +3,7 @@ package swarm_test import ( "context" "github.com/libp2p/go-libp2p-core/introspect" + introspectpb "github.com/libp2p/go-libp2p-core/introspect/pb" "github.com/libp2p/go-libp2p-core/protocol" swarm "github.com/libp2p/go-libp2p-swarm" "github.com/stretchr/testify/require" @@ -33,8 +34,7 @@ func TestConnsAndStreamIntrospect(t *testing.T) { require.NoError(t, err) // wait for the metres to kick in for { - cis, err := swarms[0].IntrospectConns(introspect.ConnectionQueryInput{Type: introspect.ConnListQueryTypeAll, - StreamOutputType: introspect.QueryOutputTypeFull}) + cis, err := swarms[0].IntrospectConnections(introspect.ConnectionQueryParams{Output: introspect.QueryOutputFull}) require.NoError(t, err) if cis[0].Traffic.TrafficOut.CumBytes != 0 { break @@ -42,23 +42,49 @@ func TestConnsAndStreamIntrospect(t *testing.T) { } // ----- Introspect Swarm 1 - cis, err := swarms[0].IntrospectConns(introspect.ConnectionQueryInput{Type: introspect.ConnListQueryTypeAll, - StreamOutputType: introspect.QueryOutputTypeFull}) + cis, err := swarms[0].IntrospectConnections(introspect.ConnectionQueryParams{Output: introspect.QueryOutputFull}) + require.NoError(t, err) // connection checks require.Len(t, cis, 1) - require.Len(t, cis[0].Streams.Streams, 2) + require.Len(t, cis[0].Streams.StreamIds, 2) require.NotEmpty(t, cis[0].Id) require.Equal(t, swarms[1].LocalPeer().String(), cis[0].PeerId) - require.Equal(t, introspect.Status_ACTIVE, cis[0].Status) - require.Equal(t, introspect.Role_INITIATOR, cis[0].Role) + require.Equal(t, introspectpb.Status_ACTIVE, cis[0].Status) + require.Equal(t, introspectpb.Role_INITIATOR, cis[0].Role) require.Equal(t, swarms[0].Conns()[0].LocalMultiaddr().String(), cis[0].Endpoints.SrcMultiaddr) require.Equal(t, swarms[0].Conns()[0].RemoteMultiaddr().String(), cis[0].Endpoints.DstMultiaddr) require.True(t, int(cis[0].Traffic.TrafficOut.CumBytes) == len(msg1)+len(msg2)) + // verify we get connectionIds correctly + cids, err := swarms[0].IntrospectConnections(introspect.ConnectionQueryParams{Output: introspect.QueryOutputList}) + require.NoError(t, err) + require.Len(t, cids, 1) + require.NotEmpty(t, cids[0].Id) + require.Empty(t, cids[0].PeerId) + + // verify we get the same result if we pass in the connection Ids + cs, err := swarms[0].IntrospectConnections(introspect.ConnectionQueryParams{introspect.QueryOutputFull, + []introspect.ConnectionID{introspect.ConnectionID(cis[0].Id)}}) + require.NoError(t, err) + require.Len(t, cs, 1) + require.Equal(t, cis[0].PeerId, cs[0].PeerId) + require.Equal(t, cis[0].Id, cs[0].Id) + + // fetch streams by reading Ids from connection + var sids []introspect.StreamID + for _, s := range cis[0].Streams.StreamIds { + sids = append(sids, introspect.StreamID(s)) + } + + // Now, introspect Streams + sl, err := swarms[0].IntrospectStreams(introspect.StreamQueryParams{introspect.QueryOutputFull, sids}) + require.Len(t, sl.Streams, 2) + require.NoError(t, err) + // map stream to protocols - protocolToStream := make(map[string]*introspect.Stream) - for _, s := range cis[0].Streams.Streams { + protocolToStream := make(map[string]*introspectpb.Stream) + for _, s := range sl.Streams { protocolToStream[s.Protocol] = s } @@ -66,8 +92,8 @@ func TestConnsAndStreamIntrospect(t *testing.T) { stream1 := protocolToStream["1"] require.NotEmpty(t, stream1) require.Equal(t, "1", stream1.Protocol) - require.Equal(t, introspect.Role_INITIATOR, stream1.Role) - require.Equal(t, introspect.Status_ACTIVE, stream1.Status) + require.Equal(t, introspectpb.Role_INITIATOR, stream1.Role) + require.Equal(t, introspectpb.Status_ACTIVE, stream1.Status) require.NotEmpty(t, stream1.Id) require.True(t, len(msg1) == int(stream1.Traffic.TrafficOut.CumBytes)) require.True(t, 0 == int(stream1.Traffic.TrafficIn.CumBytes)) @@ -76,25 +102,23 @@ func TestConnsAndStreamIntrospect(t *testing.T) { stream2 := protocolToStream["2"] require.NotEmpty(t, stream2) require.Equal(t, "2", stream2.Protocol) - require.Equal(t, introspect.Role_INITIATOR, stream2.Role) - require.Equal(t, introspect.Status_ACTIVE, stream2.Status) + require.Equal(t, introspectpb.Role_INITIATOR, stream2.Role) + require.Equal(t, introspectpb.Status_ACTIVE, stream2.Status) require.NotEmpty(t, stream2.Id) require.NotEqual(t, stream2.Id, stream1.Id) require.True(t, len(msg2) == int(stream2.Traffic.TrafficOut.CumBytes)) require.True(t, 0 == int(stream2.Traffic.TrafficIn.CumBytes)) - // reset stream 1 & verify - require.NoError(t, s1.Reset()) - cis, err = swarms[0].IntrospectConns(introspect.ConnectionQueryInput{Type: introspect.ConnListQueryTypeAll, - StreamOutputType: introspect.QueryOutputTypeFull}) + // Assert query ONLY for streaIds + streamList, err := swarms[0].IntrospectStreams(introspect.StreamQueryParams{Output: introspect.QueryOutputList}) require.NoError(t, err) - require.Len(t, cis[0].Streams.Streams, 1) + require.Len(t, streamList.Streams, 0) + require.Len(t, streamList.StreamIds, 2) - // test for stream Ids - cis, err = swarms[0].IntrospectConns(introspect.ConnectionQueryInput{Type: introspect.ConnListQueryTypeAll, - StreamOutputType: introspect.QueryOutputTypeIds}) + // reset stream 1 & verify + require.NoError(t, s1.Reset()) + cis, err = swarms[0].IntrospectConnections(introspect.ConnectionQueryParams{Output: introspect.QueryOutputFull}) require.NoError(t, err) - require.Len(t, cis[0].Streams.Streams, 0) require.Len(t, cis[0].Streams.StreamIds, 1) // introspect traffic diff --git a/stream_introspect.go b/stream_introspect.go index 6a64968f..077cb267 100644 --- a/stream_introspect.go +++ b/stream_introspect.go @@ -1,14 +1,13 @@ package swarm import ( - "github.com/golang/protobuf/ptypes/timestamp" - "github.com/libp2p/go-libp2p-core/introspect" + introspectpb "github.com/libp2p/go-libp2p-core/introspect/pb" "github.com/libp2p/go-libp2p-core/network" ) type streamIntrospector struct { - s *Stream - c *Conn + swarm *Swarm + s *Stream } func (si *streamIntrospector) id() string { @@ -19,38 +18,38 @@ func (si *streamIntrospector) protocol() string { return string(si.s.Protocol()) } -func (si *streamIntrospector) status() introspect.Status { +func (si *streamIntrospector) status() introspectpb.Status { switch si.s.state.v { case streamOpen: - return introspect.Status_ACTIVE + return introspectpb.Status_ACTIVE case streamReset: - return introspect.Status_ERROR + return introspectpb.Status_ERROR case streamCloseBoth: - return introspect.Status_CLOSED + return introspectpb.Status_CLOSED default: - return introspect.Status_ACTIVE + return introspectpb.Status_ACTIVE } } -func (si *streamIntrospector) role() introspect.Role { +func (si *streamIntrospector) role() introspectpb.Role { if si.s.stat.Direction == network.DirInbound { - return introspect.Role_RESPONDER + return introspectpb.Role_RESPONDER } else { - return introspect.Role_INITIATOR + return introspectpb.Role_INITIATOR } } -func (si *streamIntrospector) conn() *introspect.Stream_ConnectionRef { - return &introspect.Stream_ConnectionRef{Connection: &introspect.Stream_ConnectionRef_ConnId{si.c.id}} +func (si *streamIntrospector) conn() *introspectpb.Stream_ConnectionRef { + return &introspectpb.Stream_ConnectionRef{Connection: &introspectpb.Stream_ConnectionRef_ConnId{si.s.conn.id}} } // TODO Number packets ? Is the RateIn/Out a good approximation here ? -func (si *streamIntrospector) traffic() *introspect.Traffic { - if si.c.swarm.bwc != nil { +func (si *streamIntrospector) traffic() *introspectpb.Traffic { + if si.swarm.bwc != nil { streamMetrics := si.s.conn.swarm.bwc.GetBandwidthForProtocol(si.s.Protocol()) - t := &introspect.Traffic{} - t.TrafficIn = &introspect.DataGauge{CumBytes: uint64(streamMetrics.TotalIn), InstBw: uint64(streamMetrics.RateIn)} - t.TrafficOut = &introspect.DataGauge{CumBytes: uint64(streamMetrics.TotalOut), InstBw: uint64(streamMetrics.RateOut)} + t := &introspectpb.Traffic{} + t.TrafficIn = &introspectpb.DataGauge{CumBytes: uint64(streamMetrics.TotalIn), InstBw: uint64(streamMetrics.RateIn)} + t.TrafficOut = &introspectpb.DataGauge{CumBytes: uint64(streamMetrics.TotalOut), InstBw: uint64(streamMetrics.RateOut)} return t } @@ -58,8 +57,8 @@ func (si *streamIntrospector) traffic() *introspect.Traffic { } // TODO What about closed time ? -func (si *streamIntrospector) timeline() *introspect.Stream_Timeline { - return &introspect.Stream_Timeline{OpenTs: ×tamp.Timestamp{Seconds: si.s.openTime.Unix()}} +func (si *streamIntrospector) timeline() *introspectpb.Stream_Timeline { + return &introspectpb.Stream_Timeline{OpenTs: &si.s.openTime} } // TODO How ? diff --git a/swarm.go b/swarm.go index 6639e77d..14c338ec 100644 --- a/swarm.go +++ b/swarm.go @@ -119,9 +119,10 @@ func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc s.ctx = goprocessctx.OnClosingContext(s.proc) if introspector != nil { - if err := introspector.RegisterProviders(&introspect.ProvidersMap{ - Connection: s.IntrospectConns, + if err := introspector.RegisterDataProviders(&introspect.DataProviders{ + Connection: s.IntrospectConnections, Traffic: s.IntrospectTraffic, + Stream: s.IntrospectStreams, }); err != nil { log.Errorf("swarm failed to register itself as a provider with the introspector, err=%s", err) } From f3921748d4761ffde9d77a7a61cf9435814bb8da Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Wed, 5 Feb 2020 19:13:41 +0530 Subject: [PATCH 08/13] ignore the relayed over field for now --- conn_introspect.go | 2 +- introspect.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conn_introspect.go b/conn_introspect.go index a241e6ad..ae59b7a3 100644 --- a/conn_introspect.go +++ b/conn_introspect.go @@ -90,6 +90,6 @@ func (ci *connIntrospector) userProvidedTags() []string { } // TODO What's this & how to fetch it ? -func (ci *connIntrospector) relayedOver() *introspectpb.Connection_Conn { +func (ci *connIntrospector) relayedOver() *introspectpb.Connection_ConnId { return nil } diff --git a/introspect.go b/introspect.go index c14a1ca6..cf6f1033 100644 --- a/introspect.go +++ b/introspect.go @@ -94,7 +94,7 @@ func (swarm *Swarm) introspectConnection(c *Conn) (*introspectpb.Connection, err ic.TransportId = ci.transportId() ic.UserProvidedTags = ci.userProvidedTags() ic.LatencyNs = ci.latencyNs() - ic.RelayedOver = ci.relayedOver() + ic.RelayedOver = nil//ci.relayedOver() return ic, nil From 968570735e0ebd17b79ff78a18c3ac709a09c84c Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Wed, 5 Feb 2020 19:13:55 +0530 Subject: [PATCH 09/13] fmt --- introspect.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/introspect.go b/introspect.go index cf6f1033..3c7d1b35 100644 --- a/introspect.go +++ b/introspect.go @@ -94,7 +94,7 @@ func (swarm *Swarm) introspectConnection(c *Conn) (*introspectpb.Connection, err ic.TransportId = ci.transportId() ic.UserProvidedTags = ci.userProvidedTags() ic.LatencyNs = ci.latencyNs() - ic.RelayedOver = nil//ci.relayedOver() + ic.RelayedOver = nil //ci.relayedOver() return ic, nil From e8d5424296d58d0788f5c3c148bf0a0e0447e846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Mon, 10 Feb 2020 13:11:00 +0000 Subject: [PATCH 10/13] swarm introspection: review. --- conn_introspect.go | 95 ------------- introspect.go | 307 +++++++++++++++++++++++++------------------ introspect_test.go | 54 ++++---- stream_introspect.go | 72 ---------- swarm.go | 15 ++- swarm_conn.go | 20 +-- swarm_stream.go | 8 +- 7 files changed, 232 insertions(+), 339 deletions(-) delete mode 100644 conn_introspect.go delete mode 100644 stream_introspect.go diff --git a/conn_introspect.go b/conn_introspect.go deleted file mode 100644 index ae59b7a3..00000000 --- a/conn_introspect.go +++ /dev/null @@ -1,95 +0,0 @@ -package swarm - -import ( - introspectpb "github.com/libp2p/go-libp2p-core/introspect/pb" - "github.com/libp2p/go-libp2p-core/network" -) - -type connIntrospector struct { - c *Conn - s *Swarm -} - -func (ci *connIntrospector) id() string { - return ci.c.id -} - -func (ci *connIntrospector) remotePeerId() string { - return ci.c.RemotePeer().String() -} - -func (ci *connIntrospector) endPoints() *introspectpb.EndpointPair { - return &introspectpb.EndpointPair{SrcMultiaddr: ci.c.LocalMultiaddr().String(), DstMultiaddr: ci.c.RemoteMultiaddr().String()} -} - -func (ci *connIntrospector) role() introspectpb.Role { - if ci.c.stat.Direction == network.DirInbound { - return introspectpb.Role_RESPONDER - } else { - return introspectpb.Role_INITIATOR - } -} - -// TODO Number of packets & instantaneous bandwidth ? -// Should we have a separate "flow-metre" for a connection to prepare for a message oriented world ? -func (ci *connIntrospector) traffic() *introspectpb.Traffic { - if ci.s.bwc != nil { - t := &introspectpb.Traffic{} - t.TrafficIn = &introspectpb.DataGauge{} - t.TrafficOut = &introspectpb.DataGauge{} - for s, _ := range ci.c.streams.m { - streamMetrics := ci.s.bwc.GetBandwidthForProtocol(s.Protocol()) - t.TrafficIn.CumBytes = t.TrafficIn.CumBytes + uint64(streamMetrics.TotalIn) - t.TrafficIn.InstBw = t.TrafficIn.InstBw + uint64(streamMetrics.RateIn) - - t.TrafficOut.CumBytes = t.TrafficOut.CumBytes + uint64(streamMetrics.TotalOut) - t.TrafficOut.InstBw = t.TrafficOut.CumBytes + uint64(streamMetrics.RateOut) - } - return t - } - - return nil -} - -func (ci *connIntrospector) streams() (*introspectpb.StreamList, error) { - sl := &introspectpb.StreamList{} - for s, _ := range ci.c.streams.m { - sl.StreamIds = append(sl.StreamIds, []byte(s.id)) - } - return sl, nil -} - -// TODO Where do we get this information from ? -func (ci *connIntrospector) attribs() *introspectpb.Connection_Attributes { - return nil -} - -// TODO Where are the hook points and where do we persist closed time ? -func (ci *connIntrospector) timeline() *introspectpb.Connection_Timeline { - return nil -} - -// TODO How do we track othe states ? -func (ci *connIntrospector) status() introspectpb.Status { - return introspectpb.Status_ACTIVE -} - -// TODO What's this & how to fetch it ? -func (ci *connIntrospector) transportId() []byte { - return nil -} - -// TODO How ? -func (ci *connIntrospector) latencyNs() uint64 { - return 0 -} - -// TODO What's this ? -func (ci *connIntrospector) userProvidedTags() []string { - return nil -} - -// TODO What's this & how to fetch it ? -func (ci *connIntrospector) relayedOver() *introspectpb.Connection_ConnId { - return nil -} diff --git a/introspect.go b/introspect.go index 3c7d1b35..478fb6ad 100644 --- a/introspect.go +++ b/introspect.go @@ -1,173 +1,222 @@ package swarm import ( - "github.com/libp2p/go-libp2p-core/introspect" - introspectpb "github.com/libp2p/go-libp2p-core/introspect/pb" - "github.com/pkg/errors" + "fmt" + "math" + "strconv" + + "github.com/libp2p/go-libp2p-core/introspection" + introspect_pb "github.com/libp2p/go-libp2p-core/introspection/pb" + introspection_pb "github.com/libp2p/go-libp2p-core/introspection/pb" + "github.com/libp2p/go-libp2p-core/network" ) -// IntrospectTraffic introspects & returns the overall traffic for this peer -func (s *Swarm) IntrospectTraffic() (*introspectpb.Traffic, error) { - if s.bwc != nil { - t := &introspectpb.Traffic{} - metrics := s.bwc.GetBandwidthTotals() - - t.TrafficIn = &introspectpb.DataGauge{CumBytes: uint64(metrics.TotalIn), InstBw: uint64(metrics.RateIn)} - t.TrafficOut = &introspectpb.DataGauge{CumBytes: uint64(metrics.TotalOut), InstBw: uint64(metrics.RateOut)} +// IntrospectTraffic introspects and returns total traffic stats for this swarm. +func (s *Swarm) IntrospectTraffic() (*introspection_pb.Traffic, error) { + if s.bwc == nil { + return nil, nil + } - return t, nil + metrics := s.bwc.GetBandwidthTotals() + t := &introspection_pb.Traffic{ + TrafficIn: &introspection_pb.DataGauge{ + CumBytes: uint64(metrics.TotalIn), + InstBw: uint64(metrics.RateIn), + }, + TrafficOut: &introspection_pb.DataGauge{ + CumBytes: uint64(metrics.TotalOut), + InstBw: uint64(metrics.RateOut), + }, } - return nil, nil + return t, nil } // IntrospectConnections introspects & returns the swarm connections -func (swarm *Swarm) IntrospectConnections(query introspect.ConnectionQueryParams) ([]*introspectpb.Connection, error) { - swarm.conns.RLock() - defer swarm.conns.RUnlock() - - containsId := func(ids []introspect.ConnectionID, id string) bool { - for _, i := range ids { - if string(i) == id { - return true +func (s *Swarm) IntrospectConnections(q introspection.ConnectionQueryParams) ([]*introspection_pb.Connection, error) { + var conns []network.Conn + + switch l := len(q.Include); l { + case 0: + conns = s.Conns() + + default: + conns = make([]network.Conn, 0, l) + filter := make(map[string]struct{}, l) + for _, id := range q.Include { + filter[string(id)] = struct{}{} + } + + for _, c := range s.Conns() { + if _, ok := filter[c.(*Conn).ID()]; !ok { + continue } + conns = append(conns, c) } - return false } - var iconns []*introspectpb.Connection + introspected := make([]*introspection_pb.Connection, 0, len(conns)) - appendConnection := func(c *Conn) error { - if query.Output == introspect.QueryOutputFull { - ic, err := swarm.introspectConnection(c) - if err != nil { - return errors.Wrap(err, "failed to convert connection to introspect.Connection") - } - iconns = append(iconns, ic) - } else { - iconns = append(iconns, &introspectpb.Connection{Id: c.id}) + switch q.Output { + case introspection.QueryOutputFull: + for _, c := range conns { + ic := c.(*Conn).Introspect(s, q) + introspected = append(introspected, ic) } - return nil - } - // iterate over all connections the swarm has & resolve the ones required by the query - for _, conns := range swarm.conns.m { + case introspection.QueryOutputList: for _, c := range conns { - if query.Include != nil { - if containsId(query.Include, c.id) { - if err := appendConnection(c); err != nil { - return nil, err - } - } - } else { - if err := appendConnection(c); err != nil { - return nil, err - } - } + introspected = append(introspected, &introspection_pb.Connection{ + Id: strconv.FormatUint(uint64(c.(*Conn).id), 10), + }) } + + default: + return nil, fmt.Errorf("unexpected query type: %v", q.Output) } - return iconns, nil + + return introspected, nil } -func (swarm *Swarm) introspectConnection(c *Conn) (*introspectpb.Connection, error) { - c.streams.Lock() - defer c.streams.Unlock() +// IntrospectStreams processes a streams introspection query. +func (s *Swarm) IntrospectStreams(q introspection.StreamQueryParams) (*introspection_pb.StreamList, error) { + var streams []network.Stream - ci := &connIntrospector{c, swarm} - ic := &introspectpb.Connection{} + switch l := len(q.Include); l { + case 0: + for _, c := range s.Conns() { + for _, s := range c.GetStreams() { + streams = append(streams, s) + } + } - ic.Id = ci.id() - ic.PeerId = ci.remotePeerId() - ic.Endpoints = ci.endPoints() - ic.Role = ci.role() + default: + streams = make([]network.Stream, 0, l) + filter := make(map[string]struct{}, l) + for _, id := range q.Include { + filter[string(id)] = struct{}{} + } - streams, err := ci.streams() - if err != nil { - return nil, errors.Wrap(err, "failed to introspect stream for connection") + for _, c := range s.Conns() { + for _, s := range c.GetStreams() { + if _, ok := filter[s.(*Stream).ID()]; !ok { + continue + } + streams = append(streams, s) + } + } } - ic.Streams = streams - ic.Traffic = ci.traffic() - ic.Timeline = ci.timeline() - ic.Attribs = ci.attribs() - ic.Status = ci.status() - ic.TransportId = ci.transportId() - ic.UserProvidedTags = ci.userProvidedTags() - ic.LatencyNs = ci.latencyNs() - ic.RelayedOver = nil //ci.relayedOver() + switch q.Output { + case introspection.QueryOutputFull: + introspected := make([]*introspection_pb.Stream, 0, len(streams)) + for _, st := range streams { + is := st.(*Stream).Introspect(s, q) + introspected = append(introspected, is) + } + return &introspection_pb.StreamList{Streams: introspected}, nil - return ic, nil + case introspection.QueryOutputList: + introspected := make([]string, 0, len(streams)) + for _, st := range streams { + introspected = append(introspected, st.(*Stream).ID()) + } + return &introspection_pb.StreamList{StreamIds: introspected}, nil + } + return nil, fmt.Errorf("unexpected query type: %v", q.Output) } -func (swarm *Swarm) IntrospectStreams(query introspect.StreamQueryParams) (*introspectpb.StreamList, error) { - swarm.conns.RLock() - defer swarm.conns.RUnlock() +func (c *Conn) Introspect(s *Swarm, q introspection.ConnectionQueryParams) *introspect_pb.Connection { + stat := c.Stat() + res := &introspection_pb.Connection{ + Id: c.ID(), + Status: introspection_pb.Status_ACTIVE, + PeerId: c.RemotePeer().Pretty(), + Endpoints: &introspection_pb.EndpointPair{ + SrcMultiaddr: c.LocalMultiaddr().String(), + DstMultiaddr: c.RemoteMultiaddr().String(), + }, + Role: translateRole(stat), + Timeline: &introspection_pb.Connection_Timeline{ + OpenTs: &stat.Opened, + UpgradedTs: &stat.Opened, + // TODO ClosedTs, UpgradedTs. + }, + } - containsId := func(ids []introspect.StreamID, id string) bool { - for _, i := range ids { - if string(i) == id { - return true - } + // TODO this is a per-peer, not a per-conn measurement. In the future, when + // we have multiple connections per peer, this will produce inaccurate + // numbers. + // Also, we do not record stream-level stats. + if s.bwc != nil { + bw := s.bwc.GetBandwidthForPeer(c.RemotePeer()) + res.Traffic = &introspect_pb.Traffic{ + // TODO we don't have packet I/O stats. + TrafficIn: &introspect_pb.DataGauge{ + CumBytes: uint64(bw.TotalIn), + InstBw: uint64(math.Round(bw.RateIn)), + }, + TrafficOut: &introspect_pb.DataGauge{ + CumBytes: uint64(bw.TotalOut), + InstBw: uint64(math.Round(bw.RateOut)), + }, } - return false } - sl := &introspectpb.StreamList{} + // TODO I don't think we pin the multiplexer and the secure channel we've + // negotiated anywhere. + res.Attribs = &introspect_pb.Connection_Attributes{} - appendStream := func(s *Stream) error { - if query.Output == introspect.QueryOutputFull { - is, err := swarm.introspectStream(s) - if err != nil { - return errors.Wrap(err, "failed to convert stream to introspect.Stream") - } - sl.Streams = append(sl.Streams, is) - } else { - sl.StreamIds = append(sl.StreamIds, []byte(s.id)) - } - return nil + // TODO can we get the transport ID from the multiaddr? + res.TransportId = "unknown" + + // TODO there's the ping protocol, but that's higher than this layer. + // How do we source this? We may need some kind of latency manager. + res.LatencyNs = 0 + + c.streams.Lock() + sids := make([]string, 0, len(c.streams.m)) + for s := range c.streams.m { + sids = append(sids, s.ID()) } + c.streams.Unlock() - // iterate over all connections the swarm has & resolve the streams in the connections required by the query - for _, conns := range swarm.conns.m { - for _, c := range conns { - // range over all streams in the connection - c.streams.Lock() - defer c.streams.Unlock() - - for s, _ := range c.streams.m { - if query.Include != nil { - if containsId(query.Include, s.id) { - if err := appendStream(s); err != nil { - return nil, err - } - } - } else { - if err := appendStream(s); err != nil { - return nil, err - } - } - } + res.Streams = &introspection_pb.StreamList{StreamIds: sids} - } + return res +} + +func (s *Stream) Introspect(sw *Swarm, q introspection.StreamQueryParams) *introspect_pb.Stream { + stat := s.Stat() + res := &introspection_pb.Stream{ + Id: s.ID(), + Status: introspect_pb.Status_ACTIVE, + Conn: &introspect_pb.Stream_ConnectionRef{ + Connection: &introspection_pb.Stream_ConnectionRef_ConnId{ + ConnId: strconv.FormatUint(uint64(s.conn.id), 10), + }, + }, + Protocol: string(s.Protocol()), + Role: translateRole(stat), + Timeline: &introspect_pb.Stream_Timeline{ + OpenTs: &stat.Opened, + // TODO CloseTs. + }, + // TODO Traffic: we are not tracking per-stream traffic stats at the + // moment. } - return sl, nil + + return res } -func (swarm *Swarm) introspectStream(s *Stream) (*introspectpb.Stream, error) { - s.state.Lock() - defer s.state.Unlock() - - si := &streamIntrospector{swarm, s} - is := &introspectpb.Stream{} - is.Id = si.id() - is.Protocol = si.protocol() - is.Role = si.role() - is.Status = si.status() - is.Conn = si.conn() - is.Traffic = si.traffic() - is.Timeline = si.timeline() - is.LatencyNs = si.latency() - is.UserProvidedTags = si.userProvidedTags() - return is, nil +func translateRole(stat network.Stat) introspect_pb.Role { + switch stat.Direction { + case network.DirInbound: + return introspect_pb.Role_RESPONDER + case network.DirOutbound: + return introspect_pb.Role_INITIATOR + default: + return 99 // TODO placeholder value + } } diff --git a/introspect_test.go b/introspect_test.go index abee5ffc..5886fc29 100644 --- a/introspect_test.go +++ b/introspect_test.go @@ -2,12 +2,14 @@ package swarm_test import ( "context" - "github.com/libp2p/go-libp2p-core/introspect" - introspectpb "github.com/libp2p/go-libp2p-core/introspect/pb" + "testing" + + "github.com/libp2p/go-libp2p-core/introspection" + introspection_pb "github.com/libp2p/go-libp2p-core/introspection/pb" "github.com/libp2p/go-libp2p-core/protocol" swarm "github.com/libp2p/go-libp2p-swarm" + "github.com/stretchr/testify/require" - "testing" ) func TestConnsAndStreamIntrospect(t *testing.T) { @@ -32,17 +34,19 @@ func TestConnsAndStreamIntrospect(t *testing.T) { require.NoError(t, err) _, err = s2.Write([]byte(msg2)) require.NoError(t, err) - // wait for the metres to kick in + + // wait for the metrics to kick in for { - cis, err := swarms[0].IntrospectConnections(introspect.ConnectionQueryParams{Output: introspect.QueryOutputFull}) + cis, err := swarms[0].IntrospectConnections(introspection.ConnectionQueryParams{Output: introspection.QueryOutputFull}) require.NoError(t, err) + if cis[0].Traffic.TrafficOut.CumBytes != 0 { break } } // ----- Introspect Swarm 1 - cis, err := swarms[0].IntrospectConnections(introspect.ConnectionQueryParams{Output: introspect.QueryOutputFull}) + cis, err := swarms[0].IntrospectConnections(introspection.ConnectionQueryParams{Output: introspection.QueryOutputFull}) require.NoError(t, err) // connection checks @@ -50,40 +54,40 @@ func TestConnsAndStreamIntrospect(t *testing.T) { require.Len(t, cis[0].Streams.StreamIds, 2) require.NotEmpty(t, cis[0].Id) require.Equal(t, swarms[1].LocalPeer().String(), cis[0].PeerId) - require.Equal(t, introspectpb.Status_ACTIVE, cis[0].Status) - require.Equal(t, introspectpb.Role_INITIATOR, cis[0].Role) + require.Equal(t, introspection_pb.Status_ACTIVE, cis[0].Status) + require.Equal(t, introspection_pb.Role_INITIATOR, cis[0].Role) require.Equal(t, swarms[0].Conns()[0].LocalMultiaddr().String(), cis[0].Endpoints.SrcMultiaddr) require.Equal(t, swarms[0].Conns()[0].RemoteMultiaddr().String(), cis[0].Endpoints.DstMultiaddr) require.True(t, int(cis[0].Traffic.TrafficOut.CumBytes) == len(msg1)+len(msg2)) // verify we get connectionIds correctly - cids, err := swarms[0].IntrospectConnections(introspect.ConnectionQueryParams{Output: introspect.QueryOutputList}) + cids, err := swarms[0].IntrospectConnections(introspection.ConnectionQueryParams{Output: introspection.QueryOutputList}) require.NoError(t, err) require.Len(t, cids, 1) require.NotEmpty(t, cids[0].Id) require.Empty(t, cids[0].PeerId) // verify we get the same result if we pass in the connection Ids - cs, err := swarms[0].IntrospectConnections(introspect.ConnectionQueryParams{introspect.QueryOutputFull, - []introspect.ConnectionID{introspect.ConnectionID(cis[0].Id)}}) + cs, err := swarms[0].IntrospectConnections(introspection.ConnectionQueryParams{introspection.QueryOutputFull, + []introspection.ConnectionID{introspection.ConnectionID(cis[0].Id)}}) require.NoError(t, err) require.Len(t, cs, 1) require.Equal(t, cis[0].PeerId, cs[0].PeerId) require.Equal(t, cis[0].Id, cs[0].Id) // fetch streams by reading Ids from connection - var sids []introspect.StreamID + var sids []introspection.StreamID for _, s := range cis[0].Streams.StreamIds { - sids = append(sids, introspect.StreamID(s)) + sids = append(sids, introspection.StreamID(s)) } // Now, introspect Streams - sl, err := swarms[0].IntrospectStreams(introspect.StreamQueryParams{introspect.QueryOutputFull, sids}) + sl, err := swarms[0].IntrospectStreams(introspection.StreamQueryParams{introspection.QueryOutputFull, sids}) require.Len(t, sl.Streams, 2) require.NoError(t, err) // map stream to protocols - protocolToStream := make(map[string]*introspectpb.Stream) + protocolToStream := make(map[string]*introspection_pb.Stream) for _, s := range sl.Streams { protocolToStream[s.Protocol] = s } @@ -92,32 +96,32 @@ func TestConnsAndStreamIntrospect(t *testing.T) { stream1 := protocolToStream["1"] require.NotEmpty(t, stream1) require.Equal(t, "1", stream1.Protocol) - require.Equal(t, introspectpb.Role_INITIATOR, stream1.Role) - require.Equal(t, introspectpb.Status_ACTIVE, stream1.Status) + require.Equal(t, introspection_pb.Role_INITIATOR, stream1.Role) + require.Equal(t, introspection_pb.Status_ACTIVE, stream1.Status) require.NotEmpty(t, stream1.Id) - require.True(t, len(msg1) == int(stream1.Traffic.TrafficOut.CumBytes)) - require.True(t, 0 == int(stream1.Traffic.TrafficIn.CumBytes)) + // require.True(t, len(msg1) == int(stream1.Traffic.TrafficOut.CumBytes)) + // require.True(t, 0 == int(stream1.Traffic.TrafficIn.CumBytes)) // introspect stream 2 stream2 := protocolToStream["2"] require.NotEmpty(t, stream2) require.Equal(t, "2", stream2.Protocol) - require.Equal(t, introspectpb.Role_INITIATOR, stream2.Role) - require.Equal(t, introspectpb.Status_ACTIVE, stream2.Status) + require.Equal(t, introspection_pb.Role_INITIATOR, stream2.Role) + require.Equal(t, introspection_pb.Status_ACTIVE, stream2.Status) require.NotEmpty(t, stream2.Id) require.NotEqual(t, stream2.Id, stream1.Id) - require.True(t, len(msg2) == int(stream2.Traffic.TrafficOut.CumBytes)) - require.True(t, 0 == int(stream2.Traffic.TrafficIn.CumBytes)) + // require.True(t, len(msg2) == int(stream2.Traffic.TrafficOut.CumBytes)) + // require.True(t, 0 == int(stream2.Traffic.TrafficIn.CumBytes)) // Assert query ONLY for streaIds - streamList, err := swarms[0].IntrospectStreams(introspect.StreamQueryParams{Output: introspect.QueryOutputList}) + streamList, err := swarms[0].IntrospectStreams(introspection.StreamQueryParams{Output: introspection.QueryOutputList}) require.NoError(t, err) require.Len(t, streamList.Streams, 0) require.Len(t, streamList.StreamIds, 2) // reset stream 1 & verify require.NoError(t, s1.Reset()) - cis, err = swarms[0].IntrospectConnections(introspect.ConnectionQueryParams{Output: introspect.QueryOutputFull}) + cis, err = swarms[0].IntrospectConnections(introspection.ConnectionQueryParams{Output: introspection.QueryOutputFull}) require.NoError(t, err) require.Len(t, cis[0].Streams.StreamIds, 1) diff --git a/stream_introspect.go b/stream_introspect.go deleted file mode 100644 index 077cb267..00000000 --- a/stream_introspect.go +++ /dev/null @@ -1,72 +0,0 @@ -package swarm - -import ( - introspectpb "github.com/libp2p/go-libp2p-core/introspect/pb" - "github.com/libp2p/go-libp2p-core/network" -) - -type streamIntrospector struct { - swarm *Swarm - s *Stream -} - -func (si *streamIntrospector) id() string { - return si.s.id -} - -func (si *streamIntrospector) protocol() string { - return string(si.s.Protocol()) -} - -func (si *streamIntrospector) status() introspectpb.Status { - switch si.s.state.v { - case streamOpen: - return introspectpb.Status_ACTIVE - case streamReset: - return introspectpb.Status_ERROR - case streamCloseBoth: - return introspectpb.Status_CLOSED - default: - return introspectpb.Status_ACTIVE - } -} - -func (si *streamIntrospector) role() introspectpb.Role { - if si.s.stat.Direction == network.DirInbound { - return introspectpb.Role_RESPONDER - } else { - return introspectpb.Role_INITIATOR - } -} - -func (si *streamIntrospector) conn() *introspectpb.Stream_ConnectionRef { - return &introspectpb.Stream_ConnectionRef{Connection: &introspectpb.Stream_ConnectionRef_ConnId{si.s.conn.id}} -} - -// TODO Number packets ? Is the RateIn/Out a good approximation here ? -func (si *streamIntrospector) traffic() *introspectpb.Traffic { - if si.swarm.bwc != nil { - streamMetrics := si.s.conn.swarm.bwc.GetBandwidthForProtocol(si.s.Protocol()) - t := &introspectpb.Traffic{} - t.TrafficIn = &introspectpb.DataGauge{CumBytes: uint64(streamMetrics.TotalIn), InstBw: uint64(streamMetrics.RateIn)} - t.TrafficOut = &introspectpb.DataGauge{CumBytes: uint64(streamMetrics.TotalOut), InstBw: uint64(streamMetrics.RateOut)} - return t - } - - return nil -} - -// TODO What about closed time ? -func (si *streamIntrospector) timeline() *introspectpb.Stream_Timeline { - return &introspectpb.Stream_Timeline{OpenTs: &si.s.openTime} -} - -// TODO How ? -func (si *streamIntrospector) latency() uint64 { - return 0 -} - -// TODO What's this ? -func (si *streamIntrospector) userProvidedTags() []string { - return nil -} diff --git a/swarm.go b/swarm.go index 14c338ec..8e379456 100644 --- a/swarm.go +++ b/swarm.go @@ -10,7 +10,7 @@ import ( "sync/atomic" "time" - "github.com/libp2p/go-libp2p-core/introspect" + "github.com/libp2p/go-libp2p-core/introspection" "github.com/libp2p/go-libp2p-core/metrics" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" @@ -23,7 +23,6 @@ import ( filter "github.com/libp2p/go-maddr-filter" ma "github.com/multiformats/go-multiaddr" - uuid "github.com/satori/go.uuid" mafilter "github.com/whyrusleeping/multiaddr-filter" ) @@ -58,6 +57,9 @@ type Swarm struct { local peer.ID peers peerstore.Peerstore + nextConnID uint32 // guarded by atomic + nextStreamID uint32 // guarded by atomic + conns struct { sync.RWMutex m map[peer.ID][]*Conn @@ -100,7 +102,7 @@ type Swarm struct { } // NewSwarm constructs a Swarm -func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc metrics.Reporter, introspector introspect.Introspector) *Swarm { +func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc metrics.Reporter, introspector introspection.Introspector) *Swarm { s := &Swarm{ local: local, peers: peers, @@ -119,10 +121,10 @@ func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc s.ctx = goprocessctx.OnClosingContext(s.proc) if introspector != nil { - if err := introspector.RegisterDataProviders(&introspect.DataProviders{ + if err := introspector.RegisterDataProviders(&introspection.DataProviders{ Connection: s.IntrospectConnections, - Traffic: s.IntrospectTraffic, Stream: s.IntrospectStreams, + Traffic: s.IntrospectTraffic, }); err != nil { log.Errorf("swarm failed to register itself as a provider with the introspector, err=%s", err) } @@ -222,13 +224,12 @@ func (s *Swarm) addConn(tc transport.CapableConn, dir network.Direction) (*Conn, } // Wrap and register the connection. - id := uuid.NewV4() stat := network.Stat{Direction: dir} c := &Conn{ conn: tc, swarm: s, stat: stat, - id: id.String(), + id: atomic.AddUint32(&s.nextConnID, 1), } c.streams.m = make(map[*Stream]struct{}) s.conns.m[p] = append(s.conns.m[p], c) diff --git a/swarm_conn.go b/swarm_conn.go index 92d0df11..1ac8282e 100644 --- a/swarm_conn.go +++ b/swarm_conn.go @@ -3,7 +3,9 @@ package swarm import ( "errors" "fmt" + "strconv" "sync" + "sync/atomic" "time" ic "github.com/libp2p/go-libp2p-core/crypto" @@ -13,7 +15,6 @@ import ( "github.com/libp2p/go-libp2p-core/transport" ma "github.com/multiformats/go-multiaddr" - uuid "github.com/satori/go.uuid" ) // TODO: Put this elsewhere. @@ -24,7 +25,7 @@ var ErrConnClosed = errors.New("connection closed") // Conn is the connection type used by swarm. In general, you won't use this // type directly. type Conn struct { - id string + id uint32 conn transport.CapableConn swarm *Swarm @@ -41,6 +42,10 @@ type Conn struct { stat network.Stat } +func (c *Conn) ID() string { + return strconv.FormatUint(uint64(c.id), 10) +} + // Close closes this connection. // // Note: This method won't wait for the close notifications to finish as that @@ -189,16 +194,15 @@ func (c *Conn) addStream(ts mux.MuxedStream, dir network.Direction) (*Stream, er } // Wrap and register the stream. - id := uuid.NewV4() - stat := network.Stat{Direction: dir} + stat := network.Stat{ + Direction: dir, + Opened: time.Now(), + } s := &Stream{ stream: ts, conn: c, stat: stat, - id: id.String(), - connId: c.id, - // TODO Is this good enough ? - openTime: time.Now(), + id: atomic.AddUint32(&c.swarm.nextStreamID, 1), } c.streams.m[s] = struct{}{} diff --git a/swarm_stream.go b/swarm_stream.go index aa7a80c2..df7f4db8 100644 --- a/swarm_stream.go +++ b/swarm_stream.go @@ -28,9 +28,7 @@ var _ network.Stream = &Stream{} // Stream is the stream type used by swarm. In general, you won't use this type // directly. type Stream struct { - id string - connId string - openTime time.Time + id uint32 stream mux.MuxedStream conn *Conn @@ -47,6 +45,10 @@ type Stream struct { stat network.Stat } +func (s *Stream) ID() string { + return fmt.Sprintf("%d-%d", s.conn.id, s.id) +} + func (s *Stream) String() string { return fmt.Sprintf( " %s (%s)>", From 22df8272d6eb7232334763eb2cab90cda19cb580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Mon, 10 Feb 2020 13:17:26 +0000 Subject: [PATCH 11/13] swarm introspection: fix ID population. --- introspect.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/introspect.go b/introspect.go index 478fb6ad..4599d468 100644 --- a/introspect.go +++ b/introspect.go @@ -3,7 +3,6 @@ package swarm import ( "fmt" "math" - "strconv" "github.com/libp2p/go-libp2p-core/introspection" introspect_pb "github.com/libp2p/go-libp2p-core/introspection/pb" @@ -66,9 +65,7 @@ func (s *Swarm) IntrospectConnections(q introspection.ConnectionQueryParams) ([] case introspection.QueryOutputList: for _, c := range conns { - introspected = append(introspected, &introspection_pb.Connection{ - Id: strconv.FormatUint(uint64(c.(*Conn).id), 10), - }) + introspected = append(introspected, &introspection_pb.Connection{Id: c.(*Conn).ID()}) } default: @@ -194,7 +191,7 @@ func (s *Stream) Introspect(sw *Swarm, q introspection.StreamQueryParams) *intro Status: introspect_pb.Status_ACTIVE, Conn: &introspect_pb.Stream_ConnectionRef{ Connection: &introspection_pb.Stream_ConnectionRef_ConnId{ - ConnId: strconv.FormatUint(uint64(s.conn.id), 10), + ConnId: s.conn.ID(), }, }, Protocol: string(s.Protocol()), From e208c0af8758447324f0d8b37454d3157da9bf9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Mon, 10 Feb 2020 17:03:54 +0000 Subject: [PATCH 12/13] update go.mod; point to latest go-libp2p-core@feat/introspection. --- go.mod | 5 +--- go.sum | 84 ++++++++++++++++++---------------------------------------- 2 files changed, 27 insertions(+), 62 deletions(-) diff --git a/go.mod b/go.mod index 32c53009..8d2a0987 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,11 @@ module github.com/libp2p/go-libp2p-swarm require ( - github.com/golang/protobuf v1.3.2 github.com/ipfs/go-log v0.0.1 github.com/jbenet/goprocess v0.1.3 github.com/libp2p/go-addr-util v0.0.1 github.com/libp2p/go-conn-security-multistream v0.1.0 - github.com/libp2p/go-libp2p-core v0.2.5 + github.com/libp2p/go-libp2p-core v0.3.1-0.20200210163958-6d6f8284b841 github.com/libp2p/go-libp2p-loggables v0.1.0 github.com/libp2p/go-libp2p-peerstore v0.1.4 github.com/libp2p/go-libp2p-secio v0.2.1 @@ -19,8 +18,6 @@ require ( github.com/multiformats/go-multiaddr v0.2.0 github.com/multiformats/go-multiaddr-fmt v0.1.0 github.com/multiformats/go-multiaddr-net v0.1.1 - github.com/pkg/errors v0.8.1 - github.com/satori/go.uuid v1.2.0 github.com/stretchr/testify v1.4.0 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 ) diff --git a/go.sum b/go.sum index d1ef7d3e..a6f6a9a8 100644 --- a/go.sum +++ b/go.sum @@ -3,12 +3,11 @@ github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOv github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c h1:aEbSeNALREWXk0G7UdNhR3ayBV7tZ4M2PNmnrCAph6Q= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3 h1:A/EVblehb75cUgXA5njHPn0kLAsykn6mJGz7rnmW5W0= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= @@ -24,40 +23,35 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 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 v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 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/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= 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/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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 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/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 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= @@ -66,12 +60,11 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt 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.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-cid v0.0.4 h1:UlfXKrZx1DjZoBhQHmNHLC1fK1dUJDN20Y28A7s+gJ8= +github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= 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-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= -github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= github.com/ipfs/go-ds-leveldb v0.1.0/go.mod h1:hqAW8y4bwX5LWcCtku2rFNX3vjDZCy5LZCg+cSZvYb8= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= @@ -103,49 +96,36 @@ github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOS github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= -github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= -github.com/libp2p/go-flow-metrics v0.0.2 h1:U5TvqfoyR6GVRM+bC15Ux1ltar1kbj6Zw6xOVR02CZs= github.com/libp2p/go-flow-metrics v0.0.2/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= -github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM= +github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= -github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7OlyhWZ3nls5d2I= -github.com/libp2p/go-libp2p-core v0.2.0 h1:ycFtuNwtZBAJSxzaHbyv6NjG3Yj5Nmra1csHaQ3zwaw= github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= -github.com/libp2p/go-libp2p-core v0.2.2 h1:Sv1ggdoMx9c7v7FOFkR7agraHCnAgqYsXrU1ARSRUMs= github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0= -github.com/libp2p/go-libp2p-core v0.2.4 h1:Et6ykkTwI6PU44tr8qUF9k43vP0aduMNniShAbUJJw8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= -github.com/libp2p/go-libp2p-core v0.2.5 h1:iP1PIiIrlRrGbE1fYq2918yBc5NlCH3pFuIPSWU9hds= github.com/libp2p/go-libp2p-core v0.2.5/go.mod h1:6+5zJmKhsf7yHn1RbmYDu08qDUpIUxGdqHuEZckmZOA= -github.com/libp2p/go-libp2p-core v0.3.0 h1:F7PqduvrztDtFsAa/bcheQ3azmNo+Nq7m8hQY5GiUW8= +github.com/libp2p/go-libp2p-core v0.3.1-0.20200210163958-6d6f8284b841 h1:NtLkfbsEXfR1mKM901b34Pw4VpEKQmCrtV7oQE6rIPQ= +github.com/libp2p/go-libp2p-core v0.3.1-0.20200210163958-6d6f8284b841/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUhgJJLAa6almrII= github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= -github.com/libp2p/go-libp2p-peerstore v0.1.3 h1:wMgajt1uM2tMiqf4M+4qWKVyyFc8SfA+84VV9glZq1M= -github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= github.com/libp2p/go-libp2p-peerstore v0.1.4 h1:d23fvq5oYMJ/lkkbO4oTwBp/JP+I/1m5gZJobNXCE/k= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-secio v0.2.0 h1:ywzZBsWEEz2KNTn5RtzauEDq5RFEefPsttXYwAWqHng= -github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1 h1:eNWbJTdyPA7NxhP7J3c5lT97DC5d+u+IldkgCYFTPVA= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= github.com/libp2p/go-libp2p-testing v0.0.2/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.1.0 h1:WaFRj/t3HdMZGNZqnU2pS7pDRBmMeoDx7/HDNpeyT9U= 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-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-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= -github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= github.com/libp2p/go-libp2p-yamux v0.2.1 h1:Q3XYNiKCC2vIxrvUJL+Jg1kiyeEaIDNKLjgEjo3VQdI= github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= -github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.5 h1:CW3AgbMO6vUvT4kf87y4N+0P8KUl2aqLYhrGyDUbLSg= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= @@ -154,10 +134,10 @@ github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0 github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= github.com/libp2p/go-msgio v0.0.4 h1:agEFehY3zWJFUHK6SEMR7UYmk2z6kC3oeCM7ybLhguA= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= -github.com/libp2p/go-openssl v0.0.2 h1:9pP2d3Ubaxkv7ZisLjx9BFwgOGnQdQYnfcH29HNY3ls= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= -github.com/libp2p/go-openssl v0.0.3 h1:wjlG7HvQkt4Fq4cfH33Ivpwp0omaElYEi9z26qaIkIk= 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-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-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= @@ -167,8 +147,6 @@ github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROm github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= github.com/libp2p/go-tcp-transport v0.1.1 h1:yGlqURmqgNA2fvzjSgZNlHcsd/IulAnKM8Ncu+vlqnw= github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= -github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= -github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -185,9 +163,7 @@ github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0 github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771 h1:MHkK1uRtFbVqvAgvWxafZe54+5uBxLluGylDiKgdhwo= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= @@ -195,39 +171,38 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= -github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc= +github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= -github.com/multiformats/go-multiaddr v0.1.1 h1:rVAztJYMhCQ7vEFr8FvxW3mS+HF2eY/oPbOMeS0ZDnE= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= -github.com/multiformats/go-multiaddr v0.1.2 h1:HWYHNSyyllbQopmVIF5K7JKJugiah+L9/kuZKHbmNdQ= -github.com/multiformats/go-multiaddr v0.1.2/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.2.0 h1:lR52sFwcTCuQb6bTfnXF6zA2XfyYvyd+5a9qECv/J90= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= -github.com/multiformats/go-multiaddr-net v0.1.0 h1:ZepO8Ezwovd+7b5XPPDhQhayk1yt0AJpzQBpq9fejx4= github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= github.com/multiformats/go-multiaddr-net v0.1.1 h1:jFFKUuXTXv+3ARyHZi3XUqQO+YWMKgBdhEvuGRfnL6s= github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= -github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= -github.com/multiformats/go-multihash v0.0.8 h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRHGVoUugWvXg= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc= +github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= -github.com/multiformats/go-varint v0.0.1 h1:TR/0rdQtnNxuN2IhiB639xC3tWM4IUi7DkTBVTdGW/M= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg= +github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= 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.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= @@ -243,12 +218,9 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smola/gocompat v0.2.0 h1:6b1oIMlUXIpz//VKEDzPVBK8KG7beVwmHIUEBIs/Pns= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= -github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= 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= @@ -264,8 +236,8 @@ github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/ github.com/stretchr/objx v0.1.0/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.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 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/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -278,10 +250,10 @@ github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1: github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50= 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/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -289,8 +261,8 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443 h1:IcSOAf4PyMp3U3XbIEj1/xJ2BjNN2jWv7JoyOsMxXUU= golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -304,12 +276,10 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -321,13 +291,12 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -354,7 +323,6 @@ gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVY 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/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From d6136d2dca3b2d85076e871bfd4795a700766fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Mon, 10 Feb 2020 17:09:12 +0000 Subject: [PATCH 13/13] cleanup. --- swarm.go | 1 - 1 file changed, 1 deletion(-) diff --git a/swarm.go b/swarm.go index 8e379456..8b19a305 100644 --- a/swarm.go +++ b/swarm.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "strings" "sync" "sync/atomic"