From 2d3b3c6bca4067b35f09e466e8f28a8302bd7266 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 13 Dec 2021 17:49:37 +0400 Subject: [PATCH 01/22] update go-libp2p to v0.18.0 --- core/coreapi/test/api_test.go | 4 +- core/mock/mock.go | 6 +- core/node/libp2p/libp2p.go | 7 +- core/node/libp2p/smux.go | 4 +- go.mod | 28 ++--- go.sum | 122 +++++++++++++++----- peering/peering_test.go | 16 +-- test/integration/addcat_test.go | 6 +- test/integration/bench_cat_test.go | 4 +- test/integration/bitswap_wo_routing_test.go | 2 +- test/integration/three_legged_cat_test.go | 4 +- test/integration/wan_lan_dht_test.go | 6 +- 12 files changed, 136 insertions(+), 73 deletions(-) diff --git a/core/coreapi/test/api_test.go b/core/coreapi/test/api_test.go index 5c078558b7f..b8eed6102d9 100644 --- a/core/coreapi/test/api_test.go +++ b/core/coreapi/test/api_test.go @@ -23,7 +23,7 @@ import ( coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/tests" "github.com/libp2p/go-libp2p-core/crypto" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peer" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" ) @@ -32,7 +32,7 @@ const testPeerID = "QmTFauExutTsy4XP6JbMFcw2Wa9645HJt2bTqL6qYDCKfe" type NodeProvider struct{} func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) { - mn := mocknet.New(ctx) + mn := mocknet.New() nodes := make([]*core.IpfsNode, n) apis := make([]coreiface.CoreAPI, n) diff --git a/core/mock/mock.go b/core/mock/mock.go index 154917ab45a..0b34857f2b6 100644 --- a/core/mock/mock.go +++ b/core/mock/mock.go @@ -26,12 +26,10 @@ import ( // NewMockNode constructs an IpfsNode for use in tests. func NewMockNode() (*core.IpfsNode, error) { - ctx := context.Background() - // effectively offline, only peer in its network - return core.NewNode(ctx, &core.BuildCfg{ + return core.NewNode(context.Background(), &core.BuildCfg{ Online: true, - Host: MockHostOption(mocknet.New(ctx)), + Host: MockHostOption(mocknet.New()), }) } diff --git a/core/node/libp2p/libp2p.go b/core/node/libp2p/libp2p.go index 9d864ad467b..59e9a37d4df 100644 --- a/core/node/libp2p/libp2p.go +++ b/core/node/libp2p/libp2p.go @@ -10,10 +10,10 @@ import ( logging "github.com/ipfs/go-log" "github.com/libp2p/go-libp2p" - connmgr "github.com/libp2p/go-libp2p-connmgr" "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/p2p/net/connmgr" "go.uber.org/fx" ) @@ -30,7 +30,10 @@ var UserAgent = simpleOpt(libp2p.UserAgent(version.GetUserAgentVersion())) func ConnectionManager(low, high int, grace time.Duration) func() (opts Libp2pOpts, err error) { return func() (opts Libp2pOpts, err error) { - cm := connmgr.NewConnManager(low, high, grace) + cm, err := connmgr.NewConnManager(low, high, connmgr.WithGracePeriod(grace)) + if err != nil { + return opts, err + } opts.Opts = append(opts.Opts, libp2p.ConnectionManager(cm)) return } diff --git a/core/node/libp2p/smux.go b/core/node/libp2p/smux.go index a405e5a3274..539cad30788 100644 --- a/core/node/libp2p/smux.go +++ b/core/node/libp2p/smux.go @@ -7,12 +7,12 @@ import ( config "github.com/ipfs/go-ipfs/config" "github.com/libp2p/go-libp2p" - smux "github.com/libp2p/go-libp2p-core/mux" + "github.com/libp2p/go-libp2p-core/network" mplex "github.com/libp2p/go-libp2p-mplex" yamux "github.com/libp2p/go-libp2p-yamux" ) -func yamuxTransport() smux.Multiplexer { +func yamuxTransport() network.Multiplexer { tpt := *yamux.DefaultTransport tpt.AcceptBacklog = 512 if os.Getenv("YAMUX_DEBUG") != "" { diff --git a/go.mod b/go.mod index 1fd95dee40d..8f9d71d6ad9 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/ipfs/go-datastore v0.5.1 github.com/ipfs/go-detect-race v0.0.1 github.com/ipfs/go-ds-badger v0.3.0 - github.com/ipfs/go-ds-flatfs v0.5.1 + github.com/ipfs/go-ds-flatfs v0.5.0 github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fetcher v1.6.1 @@ -61,37 +61,37 @@ require ( github.com/ipfs/tar-utils v0.0.2 github.com/ipld/go-car v0.3.2 github.com/ipld/go-codec-dagpb v1.3.0 - github.com/ipld/go-ipld-prime v0.14.2 + github.com/ipld/go-ipld-prime v0.14.1 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-temp-err-catcher v0.1.0 github.com/jbenet/goprocess v0.1.4 github.com/libp2p/go-doh-resolver v0.4.0 - github.com/libp2p/go-libp2p v0.16.0 - github.com/libp2p/go-libp2p-connmgr v0.2.4 - github.com/libp2p/go-libp2p-core v0.11.0 + github.com/libp2p/go-libp2p v0.18.0 + github.com/libp2p/go-libp2p-connmgr v0.3.2-0.20220115145817-a7820a5879c7 // indirect + github.com/libp2p/go-libp2p-core v0.14.0 github.com/libp2p/go-libp2p-discovery v0.6.0 github.com/libp2p/go-libp2p-http v0.2.1 github.com/libp2p/go-libp2p-kad-dht v0.15.0 github.com/libp2p/go-libp2p-kbucket v0.4.7 github.com/libp2p/go-libp2p-loggables v0.1.0 - github.com/libp2p/go-libp2p-mplex v0.4.1 + github.com/libp2p/go-libp2p-mplex v0.6.0 github.com/libp2p/go-libp2p-noise v0.3.0 - github.com/libp2p/go-libp2p-peerstore v0.4.0 + github.com/libp2p/go-libp2p-peerstore v0.6.0 github.com/libp2p/go-libp2p-pubsub v0.6.0 github.com/libp2p/go-libp2p-pubsub-router v0.5.0 - github.com/libp2p/go-libp2p-quic-transport v0.15.0 + github.com/libp2p/go-libp2p-quic-transport v0.16.1 github.com/libp2p/go-libp2p-record v0.1.3 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 - github.com/libp2p/go-libp2p-swarm v0.8.0 - github.com/libp2p/go-libp2p-testing v0.5.0 + github.com/libp2p/go-libp2p-swarm v0.10.2 + github.com/libp2p/go-libp2p-testing v0.8.0 github.com/libp2p/go-libp2p-tls v0.3.1 - github.com/libp2p/go-libp2p-yamux v0.6.0 + github.com/libp2p/go-libp2p-yamux v0.8.2 github.com/libp2p/go-socket-activation v0.1.0 - github.com/libp2p/go-tcp-transport v0.4.0 - github.com/libp2p/go-ws-transport v0.5.0 + github.com/libp2p/go-tcp-transport v0.5.1 + github.com/libp2p/go-ws-transport v0.6.0 github.com/miekg/dns v1.1.43 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.4.1 + github.com/multiformats/go-multiaddr v0.5.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.0.3 github.com/multiformats/go-multicodec v0.3.0 diff --git a/go.sum b/go.sum index 43f65b68404..de4ea27884e 100644 --- a/go.sum +++ b/go.sum @@ -132,6 +132,7 @@ github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuP github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -139,6 +140,8 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327 h1:7grrpcfCtbZLsjtB0DgMuzs1umsJmpzaHMZ6cO6iAWw= +github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -149,11 +152,13 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d h1:t5Wuyh53qYyg9eqn4BbnlIT+vmhyww0TatL+zT3uWgI= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -180,6 +185,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -187,6 +194,8 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elastic/gosigar v0.12.0 h1:AsdhYCJlTudhfOYQyFNgx+fIVTfrDO0V1ST0vHgiapU= +github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 h1:QV0ZrfBLpFc2KDk+a4LJefDczXnonRwrYrQJY/9L4dA= github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302/go.mod h1:qBlWZqWeVx9BjvqBsnC/8RUlAYpIFmPvgROcw0n1scE= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= @@ -242,6 +251,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -298,6 +308,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -443,8 +454,8 @@ github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBR github.com/ipfs/go-ds-badger v0.2.7/go.mod h1:02rnztVKA4aZwDuaRPTf8mpqcKmXP7mLl6JPxd14JHA= github.com/ipfs/go-ds-badger v0.3.0 h1:xREL3V0EH9S219kFFueOYJJTcjgNSZ2HY1iSvN7U1Ro= github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek= -github.com/ipfs/go-ds-flatfs v0.5.1 h1:ZCIO/kQOS/PSh3vcF1H6a8fkRGS7pOfwfPdx4n/KJH4= -github.com/ipfs/go-ds-flatfs v0.5.1/go.mod h1:RWTV7oZD/yZYBKdbVIFXTX2fdY2Tbvl94NsWqmoyAX4= +github.com/ipfs/go-ds-flatfs v0.5.0 h1:ntq2P05cC51VOSZ0VO/HRaCoLefVXNKGRu9gYr9Ajko= +github.com/ipfs/go-ds-flatfs v0.5.0/go.mod h1:RWTV7oZD/yZYBKdbVIFXTX2fdY2Tbvl94NsWqmoyAX4= 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-ds-leveldb v0.4.1/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= @@ -538,8 +549,10 @@ github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= -github.com/ipfs/go-log/v2 v2.3.0 h1:31Re/cPqFHpsRHgyVwjWADPoF0otB1WrjTy8ZFYwEZU= github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= +github.com/ipfs/go-log/v2 v2.4.0/go.mod h1:nPZnh7Cj7lwS3LpRU5Mwr2ol1c2gXIEXuF6aywqrtmo= +github.com/ipfs/go-log/v2 v2.5.0 h1:+MhAooFd9XZNvR0i9FriKW6HB0ql7HNXUuflWtc0dd4= +github.com/ipfs/go-log/v2 v2.5.0/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= @@ -590,9 +603,8 @@ github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/j github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= github.com/ipld/go-ipld-prime v0.12.3/go.mod h1:PaeLYq8k6dJLmDUSLrzkEpoGV4PEfe/1OtFN/eALOc8= +github.com/ipld/go-ipld-prime v0.14.1 h1:n9obcUnuqPK34HlfbiB+o9GhXE/x59uue4z9YTsaoj4= github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= -github.com/ipld/go-ipld-prime v0.14.2 h1:P5fO2usnisXwrN/1sR5exCgEvINg/w/27EuYPKB/zx8= -github.com/ipld/go-ipld-prime v0.14.2/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= @@ -635,8 +647,9 @@ github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHz github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= @@ -660,7 +673,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= -github.com/libp2p/go-addr-util v0.1.0 h1:acKsntI33w2bTU7tC9a0SaPimJGfSI0bFKC18ChxeVI= github.com/libp2p/go-addr-util v0.1.0/go.mod h1:6I3ZYuFr2O/9D+SoyM0zEw0EF3YkldtTX406BpdQMqw= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= @@ -694,8 +706,9 @@ github.com/libp2p/go-libp2p v0.12.0/go.mod h1:FpHZrfC1q7nA8jitvdjKBDF31hguaC676g github.com/libp2p/go-libp2p v0.13.0/go.mod h1:pM0beYdACRfHO1WcJlp65WXyG2A6NqYM+t2DTVAJxMo= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= github.com/libp2p/go-libp2p v0.14.4/go.mod h1:EIRU0Of4J5S8rkockZM7eJp2S0UrCyi55m2kJVru3rM= -github.com/libp2p/go-libp2p v0.16.0 h1:aTxzQPllnW+nyC9mY8xaS20BbcrSYMt1HCkjZRHvdGY= github.com/libp2p/go-libp2p v0.16.0/go.mod h1:ump42BsirwAWxKzsCiFnTtN1Yc+DuPu76fyMX364/O4= +github.com/libp2p/go-libp2p v0.18.0 h1:moKKKG875KNGsCjZxTIFB75ihHiVjFeWg5I4aR1pDLk= +github.com/libp2p/go-libp2p v0.18.0/go.mod h1:+veaZ9z1SZQhmc5PW78jvnnxZ89Mgvmh4cggO11ETmw= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo= github.com/libp2p/go-libp2p-asn-util v0.1.0 h1:rABPCO77SjdbJ/eJ/ynIo8vWICy1VEnL5JAxJbQLo1E= github.com/libp2p/go-libp2p-asn-util v0.1.0/go.mod h1:wu+AnM9Ii2KgO5jMmS1rz9dvzTdj8BXqsPR9HR0XB7I= @@ -707,21 +720,23 @@ github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRk github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= github.com/libp2p/go-libp2p-autonat v0.4.0/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= -github.com/libp2p/go-libp2p-autonat v0.6.0 h1:+vbQ1pMzMGjE/RJopiQKK2FRjdCKHPNPrkPm8u+luQU= github.com/libp2p/go-libp2p-autonat v0.6.0/go.mod h1:bFC6kY8jwzNNWoqc8iGE57vsfwyJ/lP4O4DOV1e0B2o= github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= -github.com/libp2p/go-libp2p-blankhost v0.2.0 h1:3EsGAi0CBGcZ33GwRuXEYJLLPoVWyXJ1bcJzAJjINkk= github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= +github.com/libp2p/go-libp2p-blankhost v0.3.0 h1:kTnLArltMabZlzY63pgGDA4kkUcLkBFSM98zBssn/IY= +github.com/libp2p/go-libp2p-blankhost v0.3.0/go.mod h1:urPC+7U01nCGgJ3ZsV8jdwTp6Ji9ID0dMTvq+aJ+nZU= github.com/libp2p/go-libp2p-circuit v0.0.9/go.mod h1:uU+IBvEQzCu953/ps7bYzC/D/R0Ho2A9LfKVVCatlqU= github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3xkAcs3gnksxY7osU= github.com/libp2p/go-libp2p-circuit v0.2.1/go.mod h1:BXPwYDN5A8z4OEY9sOfr2DUQMLQvKt/6oku45YUmjIo= -github.com/libp2p/go-libp2p-circuit v0.4.0 h1:eqQ3sEYkGTtybWgr6JLqJY6QLtPWRErvFjFDfAOO1wc= github.com/libp2p/go-libp2p-circuit v0.4.0/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA= -github.com/libp2p/go-libp2p-connmgr v0.2.4 h1:TMS0vc0TCBomtQJyWr7fYxcVYYhx+q/2gF++G5Jkl/w= +github.com/libp2p/go-libp2p-circuit v0.6.0 h1:rw/HlhmUB3OktS/Ygz6+2XABOmHKzZpPUuMNUMosj8w= +github.com/libp2p/go-libp2p-circuit v0.6.0/go.mod h1:kB8hY+zCpMeScyvFrKrGicRdid6vNXbunKE4rXATZ0M= github.com/libp2p/go-libp2p-connmgr v0.2.4/go.mod h1:YV0b/RIm8NGPnnNWM7hG9Q38OeQiQfKhHCCs1++ufn0= +github.com/libp2p/go-libp2p-connmgr v0.3.2-0.20220115145817-a7820a5879c7 h1:74g7rKhKikoMDKNtpeSjttE5ELgpmk2gD7U1nqDgoPw= +github.com/libp2p/go-libp2p-connmgr v0.3.2-0.20220115145817-a7820a5879c7/go.mod h1:RVoyPjJm0J9Vd1m6qUN2Tn7kJm4rL1Ml20pFsFgPGik= github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE= @@ -750,8 +765,11 @@ github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJB github.com/libp2p/go-libp2p-core v0.8.6/go.mod h1:dgHr0l0hIKfWpGpqAMbpo19pen9wJfdCGv51mTmdpmM= github.com/libp2p/go-libp2p-core v0.9.0/go.mod h1:ESsbz31oC3C1AvMJoGx26RTuCkNhmkSRCqZ0kQtJ2/8= github.com/libp2p/go-libp2p-core v0.10.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= -github.com/libp2p/go-libp2p-core v0.11.0 h1:75jAgdA+IChNa+/mZXogfmrGkgwxkVvxmIC7pV+F6sI= github.com/libp2p/go-libp2p-core v0.11.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.12.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.13.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.14.0 h1:0kYSgiK/D7Eo28GTuRXo5YHsWwAisVpFCqCVPUd/vJs= +github.com/libp2p/go-libp2p-core v0.14.0/go.mod h1:tLasfcVdTXnixsLB0QYaT1syJOhsbrhG7q6pGrHtBg8= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= @@ -788,8 +806,10 @@ github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= github.com/libp2p/go-libp2p-mplex v0.3.0/go.mod h1:l9QWxRbbb5/hQMECEb908GbS9Sm2UAR2KFZKUJEynEs= github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= -github.com/libp2p/go-libp2p-mplex v0.4.1 h1:/pyhkP1nLwjG3OM+VuaNJkQT/Pqq73WzB3aDN3Fx1sc= github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= +github.com/libp2p/go-libp2p-mplex v0.5.0/go.mod h1:eLImPJLkj3iG5t5lq68w3Vm5NAQ5BcKwrrb2VmOYb3M= +github.com/libp2p/go-libp2p-mplex v0.6.0 h1:5ubK4/vLE2JkogKlJ2JLeXcSfA6qY6mE2HMJV9ve/Sk= +github.com/libp2p/go-libp2p-mplex v0.6.0/go.mod h1:i3usuPrBbh9FD2fLZjGpotyNkwr42KStYZQY7BeTiu4= github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= github.com/libp2p/go-libp2p-nat v0.0.5/go.mod h1:1qubaE5bTZMJE+E/uu2URroMbzdubFz1ChgiN79yKPE= github.com/libp2p/go-libp2p-nat v0.0.6/go.mod h1:iV59LVhB3IkFvS6S6sauVTSOrNEANnINbI/fkaLimiw= @@ -818,8 +838,9 @@ github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRj github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-peerstore v0.2.7/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-peerstore v0.2.8/go.mod h1:gGiPlXdz7mIHd2vfAsHzBNAMqSDkt2UBFwgcITgw1lA= -github.com/libp2p/go-libp2p-peerstore v0.4.0 h1:DOhRJLnM9Dc9lIXi3rPDZBf789LXy1BrzwIs7Tj0cKA= github.com/libp2p/go-libp2p-peerstore v0.4.0/go.mod h1:rDJUFyzEWPpXpEwywkcTYYzDHlwza8riYMaUzaN6hX0= +github.com/libp2p/go-libp2p-peerstore v0.6.0 h1:HJminhQSGISBIRb93N6WK3t6Fa8OOTnHd/VBjL4mY5A= +github.com/libp2p/go-libp2p-peerstore v0.6.0/go.mod h1:DGEmKdXrcYpK9Jha3sS7MhqYdInxJy84bIPtSu65bKc= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= @@ -831,13 +852,17 @@ github.com/libp2p/go-libp2p-pubsub-router v0.5.0/go.mod h1:TRJKskSem3C0aSb3CmRgP github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= github.com/libp2p/go-libp2p-quic-transport v0.11.2/go.mod h1:wlanzKtIh6pHrq+0U3p3DY9PJfGqxMgPaGKaK5LifwQ= github.com/libp2p/go-libp2p-quic-transport v0.13.0/go.mod h1:39/ZWJ1TW/jx1iFkKzzUg00W6tDJh73FC0xYudjr7Hc= -github.com/libp2p/go-libp2p-quic-transport v0.15.0 h1:DR0mP6kcieowikBprWkcNtbquRKOPWb5dLZ4ahDZujk= github.com/libp2p/go-libp2p-quic-transport v0.15.0/go.mod h1:wv4uGwjcqe8Mhjj7N/Ic0aKjA+/10UnMlSzLO0yRpYQ= +github.com/libp2p/go-libp2p-quic-transport v0.16.0/go.mod h1:1BXjVMzr+w7EkPfiHkKnwsWjPjtfaNT0q8RS3tGDvEQ= +github.com/libp2p/go-libp2p-quic-transport v0.16.1 h1:N/XqYXHurphPLDfXYhll8NyqzdZYQqAF4GIr7+SmLV8= +github.com/libp2p/go-libp2p-quic-transport v0.16.1/go.mod h1:1BXjVMzr+w7EkPfiHkKnwsWjPjtfaNT0q8RS3tGDvEQ= github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.1.2/go.mod h1:pal0eNcT5nqZaTV7UGhqeGqxFgGdsU/9W//C8dqjQDk= github.com/libp2p/go-libp2p-record v0.1.3 h1:R27hoScIhQf/A8XJZ8lYpnqh9LatJ5YbHs28kCIfql0= github.com/libp2p/go-libp2p-record v0.1.3/go.mod h1:yNUff/adKIfPnYQXgp6FQmNu3gLJ6EMg7+/vv2+9pY4= +github.com/libp2p/go-libp2p-resource-manager v0.1.5 h1:7J6t9KLFS0MxXDTfqA6rwfVCZl/yLQnXW5LpZjHAANI= +github.com/libp2p/go-libp2p-resource-manager v0.1.5/go.mod h1:wJPNjeE4XQlxeidwqVY5G6DLOKqFK33u2n8blpl0I6Y= github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= github.com/libp2p/go-libp2p-routing-helpers v0.2.3 h1:xY61alxJ6PurSi+MXbywZpelvuU4U4p/gPTxjqCqTzY= github.com/libp2p/go-libp2p-routing-helpers v0.2.3/go.mod h1:795bh+9YeoFl99rMASoiVgHdi5bjack0N1+AFAdbvBw= @@ -856,8 +881,10 @@ github.com/libp2p/go-libp2p-swarm v0.3.1/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJeg github.com/libp2p/go-libp2p-swarm v0.4.0/go.mod h1:XVFcO52VoLoo0eitSxNQWYq4D6sydGOweTOAjJNraCw= github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= github.com/libp2p/go-libp2p-swarm v0.5.3/go.mod h1:NBn7eNW2lu568L7Ns9wdFrOhgRlkRnIDg0FLKbuu3i8= -github.com/libp2p/go-libp2p-swarm v0.8.0 h1:nRHNRhi86L7jhka02N4MoV+PSFFPoJFkHNQwCTFxNhw= github.com/libp2p/go-libp2p-swarm v0.8.0/go.mod h1:sOMp6dPuqco0r0GHTzfVheVBh6UEL0L1lXUZ5ot2Fvc= +github.com/libp2p/go-libp2p-swarm v0.10.0/go.mod h1:71ceMcV6Rg/0rIQ97rsZWMzto1l9LnNquef+efcRbmA= +github.com/libp2p/go-libp2p-swarm v0.10.2 h1:UaXf+CTq6Ns1N2V1EgqJ9Q3xaRsiN7ImVlDMpirMAWw= +github.com/libp2p/go-libp2p-swarm v0.10.2/go.mod h1:Pdkq0QU5a+qu+oyqIV3bknMsnzk9lnNyKvB9acJ5aZs= github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= 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= @@ -868,8 +895,10 @@ github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= github.com/libp2p/go-libp2p-testing v0.4.2/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= -github.com/libp2p/go-libp2p-testing v0.5.0 h1:bTjC29TTQ/ODq0ld3+0KLq3irdA5cAH3OMbRi0/QsvE= github.com/libp2p/go-libp2p-testing v0.5.0/go.mod h1:QBk8fqIL1XNcno/l3/hhaIEn4aLRijpYOR+zVjjlh+A= +github.com/libp2p/go-libp2p-testing v0.7.0/go.mod h1:OLbdn9DbgdMwv00v+tlp1l3oe2Cl+FAjoWIA2pa0X6E= +github.com/libp2p/go-libp2p-testing v0.8.0 h1:/te8SOIyj5sGH5Jr1Uoo+qYB00aK8O4+yHGzLgfE3kc= +github.com/libp2p/go-libp2p-testing v0.8.0/go.mod h1:gRdsNxQSxAZowTgcLY7CC33xPmleZzoBpqSYbWenqPc= github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= github.com/libp2p/go-libp2p-tls v0.3.0/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= github.com/libp2p/go-libp2p-tls v0.3.1 h1:lsE2zYte+rZCEOHF72J1Fg3XK3dGQyKvI6i5ehJfEp0= @@ -884,8 +913,10 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.4.0/go.mod h1:J4ko0ObtZSmgn5BX github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= github.com/libp2p/go-libp2p-transport-upgrader v0.4.3/go.mod h1:bpkldbOWXMrXhpZbSV1mQxTrefOg2Fi+k1ClDSA4ppw= github.com/libp2p/go-libp2p-transport-upgrader v0.4.6/go.mod h1:JE0WQuQdy+uLZ5zOaI3Nw9dWGYJIA7mywEtP2lMvnyk= -github.com/libp2p/go-libp2p-transport-upgrader v0.5.0 h1:7SDl3O2+AYOgfE40Mis83ClpfGNkNA6m4FwhbOHs+iI= github.com/libp2p/go-libp2p-transport-upgrader v0.5.0/go.mod h1:Rc+XODlB3yce7dvFV4q/RmyJGsFcCZRkeZMu/Zdg0mo= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.0/go.mod h1:GIR2aTRp1J5yjVlkUoFqMkdobfob6RnAwYg/RZPhrzg= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.1 h1:MSMe+tUfxpC9GArTz7a4G5zQKQgGh00Vio87d3j3xIg= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.1/go.mod h1:GIR2aTRp1J5yjVlkUoFqMkdobfob6RnAwYg/RZPhrzg= github.com/libp2p/go-libp2p-xor v0.0.0-20210714161855-5c005aca55db h1:EDoDKW8ZAHd6SIDeo+thU51PyQppqLYkBxx0ObvFj/w= github.com/libp2p/go-libp2p-xor v0.0.0-20210714161855-5c005aca55db/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= @@ -900,12 +931,14 @@ github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelN github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= github.com/libp2p/go-libp2p-yamux v0.5.1/go.mod h1:dowuvDu8CRWmr0iqySMiSxK+W0iL5cMVO9S94Y6gkv4= github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= -github.com/libp2p/go-libp2p-yamux v0.6.0 h1:TKayW983n92JhCGdCo7ej7eEb+DQ0VYfKNOxlN/1kNQ= github.com/libp2p/go-libp2p-yamux v0.6.0/go.mod h1:MRhd6mAYnFRnSISp4M8i0ClV/j+mWHo2mYLifWGw33k= +github.com/libp2p/go-libp2p-yamux v0.8.0/go.mod h1:yTkPgN2ib8FHyU1ZcVD7aelzyAqXXwEPbyx+aSKm9h8= +github.com/libp2p/go-libp2p-yamux v0.8.1/go.mod h1:rUozF8Jah2dL9LLGyBaBeTQeARdwhefMCTQVQt6QobE= +github.com/libp2p/go-libp2p-yamux v0.8.2 h1:6GKWntresp0TFxMP/oSoH96nV8XKJRdynXsdp43dn0Y= +github.com/libp2p/go-libp2p-yamux v0.8.2/go.mod h1:rUozF8Jah2dL9LLGyBaBeTQeARdwhefMCTQVQt6QobE= github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= -github.com/libp2p/go-maddr-filter v0.1.0 h1:4ACqZKw8AqiuJfwFGq1CYDFugfXTOos+qQ3DETkhtCE= github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= @@ -913,8 +946,10 @@ github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6 github.com/libp2p/go-mplex v0.1.1/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= -github.com/libp2p/go-mplex v0.3.0 h1:U1T+vmCYJaEoDJPV1aq31N56hS+lJgb397GsylNSgrU= github.com/libp2p/go-mplex v0.3.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= +github.com/libp2p/go-mplex v0.4.0/go.mod h1:y26Lx+wNVtMYMaPu300Cbot5LkEZ4tJaNYeHeT9dh6E= +github.com/libp2p/go-mplex v0.6.0 h1:5kKp029zrsLVJT5q6ASt4LwuZFxj3B13wXXaGmFrWg0= +github.com/libp2p/go-mplex v0.6.0/go.mod h1:y26Lx+wNVtMYMaPu300Cbot5LkEZ4tJaNYeHeT9dh6E= github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= @@ -929,8 +964,9 @@ github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.1.5/go.mod h1:V1SR3AaECRkEQCoFFzYwVYWvYIEtlxx89+O3qcpCl4A= -github.com/libp2p/go-netroute v0.1.6 h1:ruPJStbYyXVYGQ81uzEDzuvbYRLKRrLvTYd33yomC38= github.com/libp2p/go-netroute v0.1.6/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= +github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4nWRE= +github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= @@ -949,7 +985,6 @@ github.com/libp2p/go-reuseport-transport v0.1.0 h1:C3PHeHjmnz8m6f0uydObj02tMEoi7 github.com/libp2p/go-reuseport-transport v0.1.0/go.mod h1:vev0C0uMkzriDY59yFHD9v+ujJvYmDQVLowvAjEOmfw= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-sockaddr v0.1.1 h1:yD80l2ZOdGksnOyHrhxDdTDFrf7Oy+v3FMVArIRgZxQ= github.com/libp2p/go-sockaddr v0.1.1/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-socket-activation v0.1.0 h1:OImQPhtbGlCNaF/KSTl6pBBy+chA5eBt5i9uMJNtEdY= github.com/libp2p/go-socket-activation v0.1.0/go.mod h1:gzda2dNkMG5Ti2OfWNNwW0FDIbj0g/aJJU320FcLfhk= @@ -957,8 +992,9 @@ github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= -github.com/libp2p/go-stream-muxer-multistream v0.3.0 h1:TqnSHPJEIqDEO7h1wZZ0p3DXdvDSiLHQidKKUGZtiOY= github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= +github.com/libp2p/go-stream-muxer-multistream v0.4.0 h1:HsM/9OdtqnIzjVXcxTXjmqKrj3gJ8kacaOJwJS1ipaY= +github.com/libp2p/go-stream-muxer-multistream v0.4.0/go.mod h1:nb+dGViZleRP4XcyHuZSVrJCBl55nRBOMmiSL/dyziw= github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19K427vCzQ+xHKH/o= github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= @@ -967,8 +1003,10 @@ github.com/libp2p/go-tcp-transport v0.2.1/go.mod h1:zskiJ70MEfWz2MKxvFB/Pv+tPIB1 github.com/libp2p/go-tcp-transport v0.2.3/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= github.com/libp2p/go-tcp-transport v0.2.4/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= github.com/libp2p/go-tcp-transport v0.2.7/go.mod h1:lue9p1b3VmZj1MhhEGB/etmvF/nBQ0X9CW2DutBT3MM= -github.com/libp2p/go-tcp-transport v0.4.0 h1:VDyg4j6en3OuXf90gfDQh5Sy9KowO9udnd0OU8PP6zg= github.com/libp2p/go-tcp-transport v0.4.0/go.mod h1:0y52Rwrn4076xdJYu/51/qJIdxz+EWDAOG2S45sV3VI= +github.com/libp2p/go-tcp-transport v0.5.0/go.mod h1:UPPL0DIjQqiWRwVAb+CEQlaAG0rp/mCqJfIhFcLHc4Y= +github.com/libp2p/go-tcp-transport v0.5.1 h1:edOOs688VLZAozWC7Kj5/6HHXKNwi9M6wgRmmLa8M6Q= +github.com/libp2p/go-tcp-transport v0.5.1/go.mod h1:UPPL0DIjQqiWRwVAb+CEQlaAG0rp/mCqJfIhFcLHc4Y= github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= github.com/libp2p/go-ws-transport v0.0.5/go.mod h1:Qbl4BxPfXXhhd/o0wcrgoaItHqA9tnZjoFZnxykuaXU= @@ -977,8 +1015,9 @@ github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzl github.com/libp2p/go-ws-transport v0.3.0/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= github.com/libp2p/go-ws-transport v0.3.1/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= github.com/libp2p/go-ws-transport v0.4.0/go.mod h1:EcIEKqf/7GDjth6ksuS/6p7R49V4CBY6/E7R/iyhYUA= -github.com/libp2p/go-ws-transport v0.5.0 h1:cO6x4P0v6PfxbKnxmf5cY2Ny4OPDGYkUqNvZzp/zdlo= github.com/libp2p/go-ws-transport v0.5.0/go.mod h1:I2juo1dNTbl8BKSBYo98XY85kU2xds1iamArLvl8kNg= +github.com/libp2p/go-ws-transport v0.6.0 h1:326XBL6Q+5CQ2KtjXz32+eGu02W/Kz2+Fm4SpXdr0q4= +github.com/libp2p/go-ws-transport v0.6.0/go.mod h1:dXqtI9e2JV9FtF1NOtWVZSKXh5zXvnuwPXfj8GPBbYU= github.com/libp2p/go-yamux v1.2.1/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= @@ -991,8 +1030,10 @@ github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux/v2 v2.0.0/go.mod h1:NVWira5+sVUIU6tu1JWvaRn1dRnG+cawOJiflsAM+7U= github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= -github.com/libp2p/go-yamux/v2 v2.3.0 h1:luRV68GS1vqqr6EFUjtu1kr51d+IbW0gSowu8emYWAI= github.com/libp2p/go-yamux/v2 v2.3.0/go.mod h1:iTU+lOIn/2h0AgKcL49clNTwfEw+WSfDYrXe05EyKIs= +github.com/libp2p/go-yamux/v3 v3.0.1/go.mod h1:s2LsDhHbh+RfCsQoICSYt58U2f8ijtPANFD8BmE74Bo= +github.com/libp2p/go-yamux/v3 v3.0.2 h1:LW0q5+A1Wy0npEsPJP9wmare2NH4ohNluN5EWVwv2mE= +github.com/libp2p/go-yamux/v3 v3.0.2/go.mod h1:s2LsDhHbh+RfCsQoICSYt58U2f8ijtPANFD8BmE74Bo= github.com/libp2p/zeroconf/v2 v2.1.1 h1:XAuSczA96MYkVwH+LqqqCUZb2yH3krobMJ1YE+0hG2s= github.com/libp2p/zeroconf/v2 v2.1.1/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -1000,8 +1041,9 @@ github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0U github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= github.com/lucas-clemente/quic-go v0.21.2/go.mod h1:vF5M1XqhBAHgbjKcJOXY3JZz3GP0T3FQhz/uyOUS38Q= github.com/lucas-clemente/quic-go v0.23.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= -github.com/lucas-clemente/quic-go v0.24.0 h1:ToR7SIIEdrgOhgVTHvPgdVRJfgVy+N0wQAagH7L4d5g= github.com/lucas-clemente/quic-go v0.24.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= +github.com/lucas-clemente/quic-go v0.25.0 h1:K+X9Gvd7JXsOHtU0N2icZ2Nw3rx82uBej3mP4CLgibc= +github.com/lucas-clemente/quic-go v0.25.0/go.mod h1:YtzP8bxRVCBlO77yRanE264+fY/T2U9ZlW1AaHOsMOg= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -1017,6 +1059,8 @@ github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZE github.com/marten-seemann/qtls-go1-17 v0.1.0-rc.1/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= github.com/marten-seemann/qtls-go1-17 v0.1.0 h1:P9ggrs5xtwiqXv/FHNwntmuLMNq3KaSIG93AtAZ48xk= github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= +github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1 h1:EnzzN9fPUkUck/1CuY1FlzBaIYMoiBsdwTNmNGkwUUM= +github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1/go.mod h1:PUhIQk19LoFt2174H4+an8TYvWOGjb/hHwphBeaDHwI= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -1029,8 +1073,9 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -1096,8 +1141,9 @@ github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4 github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.4.1 h1:Pq37uLx3hsyNlTDir7FZyU8+cFCTqd5y1KiM2IzOutI= github.com/multiformats/go-multiaddr v0.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= +github.com/multiformats/go-multiaddr v0.5.0 h1:i/JuOoVg4szYQ4YEzDGtb2h0o8M7CG/Yq6cGlcjWZpM= +github.com/multiformats/go-multiaddr v0.5.0/go.mod h1:3KAxNkUqLTJ20AAwN4XVX4kZar+bR+gh4zgbfr3SNug= github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0= @@ -1180,6 +1226,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -1193,6 +1241,8 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= @@ -1254,6 +1304,10 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/statsd_exporter v0.21.0 h1:hA05Q5RFeIjgwKIYEdFd59xu5Wwaznf33yKI+pyX6T8= github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3MLCHmSHelCh9hSGYNLTQ= +github.com/raulk/clock v1.1.0 h1:dpb29+UKMbLqiU/jqIJptgLR1nn23HLgMY0sTCDza5Y= +github.com/raulk/clock v1.1.0/go.mod h1:3MpVxdZ/ODBQDxbN+kzshf5OSZwPjtMDx6BBXBmOeY0= +github.com/raulk/go-watchdog v1.2.0 h1:konN75pw2BMmZ+AfuAm5rtFsWcJpKF3m02rKituuXNo= +github.com/raulk/go-watchdog v1.2.0/go.mod h1:lzSbAl5sh4rtI8tYHU01BWIDzgzqaQLj6RcA1i4mlqI= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -1295,6 +1349,7 @@ github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5k github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= @@ -1345,6 +1400,7 @@ github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= @@ -1423,6 +1479,7 @@ go.uber.org/fx v1.16.0 h1:N8i80+X1DCX+qMRiKzM+jPPZiIiyK/bVCysga3+B+1w= go.uber.org/fx v1.16.0/go.mod h1:OMoT5BnXcOaiexlpjtpE4vcAmzyDKyRs9TRYXCzamx8= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -1439,6 +1496,7 @@ go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= @@ -1591,6 +1649,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1637,6 +1696,7 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/peering/peering_test.go b/peering/peering_test.go index 27c9b717514..09a54f2ce1e 100644 --- a/peering/peering_test.go +++ b/peering/peering_test.go @@ -6,20 +6,22 @@ import ( "time" "github.com/libp2p/go-libp2p" - connmgr "github.com/libp2p/go-libp2p-connmgr" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/p2p/net/connmgr" "github.com/stretchr/testify/require" ) -func newNode(ctx context.Context, t *testing.T) host.Host { +func newNode(t *testing.T) host.Host { + cm, err := connmgr.NewConnManager(1, 100, connmgr.WithGracePeriod(0)) + require.NoError(t, err) h, err := libp2p.New( libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0"), // We'd like to set the connection manager low water to 0, but // that would disable the connection manager. - libp2p.ConnectionManager(connmgr.NewConnManager(1, 100, 0)), + libp2p.ConnectionManager(cm), ) require.NoError(t, err) return h @@ -29,12 +31,12 @@ func TestPeeringService(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - h1 := newNode(ctx, t) + h1 := newNode(t) ps1 := NewPeeringService(h1) - h2 := newNode(ctx, t) - h3 := newNode(ctx, t) - h4 := newNode(ctx, t) + h2 := newNode(t) + h3 := newNode(t) + h4 := newNode(t) // peer 1 -> 2 ps1.AddPeer(peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()}) diff --git a/test/integration/addcat_test.go b/test/integration/addcat_test.go index eebc1f63f76..f564ee5ee3e 100644 --- a/test/integration/addcat_test.go +++ b/test/integration/addcat_test.go @@ -18,8 +18,8 @@ import ( mock "github.com/ipfs/go-ipfs/core/mock" "github.com/ipfs/go-ipfs/thirdparty/unit" logging "github.com/ipfs/go-log" - random "github.com/jbenet/go-random" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/jbenet/go-random" + "github.com/libp2p/go-libp2p-core/peer" testutil "github.com/libp2p/go-libp2p-testing/net" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" ) @@ -97,7 +97,7 @@ func DirectAddCat(data []byte, conf testutil.LatencyConfig) error { defer cancel() // create network - mn := mocknet.New(ctx) + mn := mocknet.New() mn.SetLinkDefaults(mocknet.LinkOptions{ Latency: conf.NetworkLatency, // TODO add to conf. This is tricky because we want 0 values to be functional. diff --git a/test/integration/bench_cat_test.go b/test/integration/bench_cat_test.go index 6115b5b54dd..45b3b9f3e28 100644 --- a/test/integration/bench_cat_test.go +++ b/test/integration/bench_cat_test.go @@ -14,7 +14,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi" mock "github.com/ipfs/go-ipfs/core/mock" "github.com/ipfs/go-ipfs/thirdparty/unit" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peer" testutil "github.com/libp2p/go-libp2p-testing/net" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" ) @@ -40,7 +40,7 @@ func benchCat(b *testing.B, data []byte, conf testutil.LatencyConfig) error { defer cancel() // create network - mn := mocknet.New(ctx) + mn := mocknet.New() mn.SetLinkDefaults(mocknet.LinkOptions{ Latency: conf.NetworkLatency, // TODO add to conf. This is tricky because we want 0 values to be functional. diff --git a/test/integration/bitswap_wo_routing_test.go b/test/integration/bitswap_wo_routing_test.go index ec0c2f11a83..9caa78c38c5 100644 --- a/test/integration/bitswap_wo_routing_test.go +++ b/test/integration/bitswap_wo_routing_test.go @@ -19,7 +19,7 @@ func TestBitswapWithoutRouting(t *testing.T) { const numPeers = 4 // create network - mn := mocknet.New(ctx) + mn := mocknet.New() var nodes []*core.IpfsNode for i := 0; i < numPeers; i++ { diff --git a/test/integration/three_legged_cat_test.go b/test/integration/three_legged_cat_test.go index eb82d00083a..009d1af32d6 100644 --- a/test/integration/three_legged_cat_test.go +++ b/test/integration/three_legged_cat_test.go @@ -15,7 +15,7 @@ import ( "github.com/ipfs/go-ipfs/thirdparty/unit" files "github.com/ipfs/go-ipfs-files" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peer" testutil "github.com/libp2p/go-libp2p-testing/net" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" ) @@ -68,7 +68,7 @@ func RunThreeLeggedCat(data []byte, conf testutil.LatencyConfig) error { defer cancel() // create network - mn := mocknet.New(ctx) + mn := mocknet.New() mn.SetLinkDefaults(mocknet.LinkOptions{ Latency: conf.NetworkLatency, // TODO add to conf. This is tricky because we want 0 values to be functional. diff --git a/test/integration/wan_lan_dht_test.go b/test/integration/wan_lan_dht_test.go index da2468d5a1e..44305e05174 100644 --- a/test/integration/wan_lan_dht_test.go +++ b/test/integration/wan_lan_dht_test.go @@ -72,7 +72,7 @@ func RunDHTConnectivity(conf testutil.LatencyConfig, numPeers int) error { defer cancel() // create network - mn := mocknet.New(ctx) + mn := mocknet.New() mn.SetLinkDefaults(mocknet.LinkOptions{ Latency: conf.NetworkLatency, Bandwidth: math.MaxInt32, @@ -209,9 +209,9 @@ WanStartupWait: for { select { case err := <-testPeer.DHT.WAN.RefreshRoutingTable(): - //if err != nil { + // if err != nil { // fmt.Printf("Error refreshing routing table: %v\n", err) - //} + // } if testPeer.DHT.WAN.RoutingTable() == nil || testPeer.DHT.WAN.RoutingTable().Size() == 0 || err != nil { From 73a197f49c45582750c16b61e68cac4e6d8094a4 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 7 Feb 2022 18:39:21 +0530 Subject: [PATCH 02/22] initialize the resource manager --- core/node/groups.go | 9 +++++---- core/node/libp2p/rcmgr.go | 40 +++++++++++++++++++++++++++++++++++++++ go.mod | 1 + 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 core/node/libp2p/rcmgr.go diff --git a/core/node/groups.go b/core/node/groups.go index 26b2fae8475..bca75c77df1 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -112,10 +112,10 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { } // If `cfg.Swarm.DisableRelay` is set and `Network.RelayTransport` isn't, use the former. - enableRelayTransport := cfg.Swarm.Transports.Network.Relay.WithDefault(!cfg.Swarm.DisableRelay) //nolint + enableRelayTransport := cfg.Swarm.Transports.Network.Relay.WithDefault(!cfg.Swarm.DisableRelay) // nolint // Warn about a deprecated option. - //nolint + // nolint if cfg.Swarm.DisableRelay { logger.Error("The 'Swarm.DisableRelay' config field is deprecated.") if enableRelayTransport { @@ -124,7 +124,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { logger.Error("Use the 'Swarm.Transports.Network.Relay' config field instead") } } - //nolint + // nolint if cfg.Swarm.EnableAutoRelay { logger.Error("The 'Swarm.EnableAutoRelay' config field is deprecated.") if cfg.Swarm.RelayClient.Enabled == config.Default { @@ -133,7 +133,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { logger.Error("'Swarm.EnableAutoRelay' has been overridden by 'Swarm.AutoRelay.Enabled'") } } - //nolint + // nolint if cfg.Swarm.EnableRelayHop { logger.Fatal("The `Swarm.EnableRelayHop` config field is ignored.\n" + "Use `Swarm.RelayService` to configure the circuit v2 relay.\n" + @@ -144,6 +144,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { opts := fx.Options( BaseLibP2P, + fx.Provide(libp2p.ResourceManager()), fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), fx.Provide(libp2p.SmuxTransport(cfg.Swarm.Transports)), diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go new file mode 100644 index 00000000000..dcd80dc4699 --- /dev/null +++ b/core/node/libp2p/rcmgr.go @@ -0,0 +1,40 @@ +package libp2p + +import ( + "errors" + "fmt" + "os" + + "github.com/libp2p/go-libp2p" + rcmgr "github.com/libp2p/go-libp2p-resource-manager" +) + +func ResourceManager() func() (Libp2pOpts, error) { + return func() (opts Libp2pOpts, err error) { + var limiter *rcmgr.BasicLimiter + + limitsIn, err := os.Open("./limits.json") + switch { + case err == nil: + defer limitsIn.Close() + limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitsIn) + if err != nil { + return opts, fmt.Errorf("error parsing limit file: %w", err) + } + case errors.Is(err, os.ErrNotExist): + limiter = rcmgr.NewDefaultLimiter() + default: + return opts, err + } + + libp2p.SetDefaultServiceLimits(limiter) + + // TODO: close the resource manager when the node is shut down + rcmgr, err := rcmgr.NewResourceManager(limiter) + if err != nil { + return opts, fmt.Errorf("error creating resource manager: %w", err) + } + opts.Opts = append(opts.Opts, libp2p.ResourceManager(rcmgr)) + return opts, nil + } +} diff --git a/go.mod b/go.mod index 8f9d71d6ad9..aefcc209e61 100644 --- a/go.mod +++ b/go.mod @@ -81,6 +81,7 @@ require ( github.com/libp2p/go-libp2p-pubsub-router v0.5.0 github.com/libp2p/go-libp2p-quic-transport v0.16.1 github.com/libp2p/go-libp2p-record v0.1.3 + github.com/libp2p/go-libp2p-resource-manager v0.1.5 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 github.com/libp2p/go-libp2p-swarm v0.10.2 github.com/libp2p/go-libp2p-testing v0.8.0 From 41eede12dbaf0f144a50ae4f7a23655bbdb068cc Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Tue, 15 Feb 2022 20:32:14 -0300 Subject: [PATCH 03/22] add resource manager stats/limit commands --- core/commands/commands_test.go | 2 + core/commands/swarm.go | 418 ++++++++++++++++++++++++++++++++- core/core.go | 24 +- core/node/groups.go | 2 + core/node/libp2p/rcmgr.go | 39 ++- 5 files changed, 447 insertions(+), 38 deletions(-) diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 964baad9299..b0980f13126 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -237,11 +237,13 @@ func TestCommands(t *testing.T) { "/swarm/filters", "/swarm/filters/add", "/swarm/filters/rm", + "/swarm/limit", "/swarm/peers", "/swarm/peering", "/swarm/peering/add", "/swarm/peering/ls", "/swarm/peering/rm", + "/swarm/stats", "/tar", "/tar/add", "/tar/cat", diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 00899eacbed..7de6d3360c4 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -1,24 +1,31 @@ package commands import ( + "bytes" "context" + "encoding/json" "errors" "fmt" "io" + "os" "path" "sort" + "strings" "sync" "time" - commands "github.com/ipfs/go-ipfs/commands" - cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" - repo "github.com/ipfs/go-ipfs/repo" - fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" + "github.com/ipfs/go-ipfs/commands" + "github.com/ipfs/go-ipfs/config" + "github.com/ipfs/go-ipfs/core/commands/cmdenv" + "github.com/ipfs/go-ipfs/repo" + "github.com/ipfs/go-ipfs/repo/fsrepo" cmds "github.com/ipfs/go-ipfs-cmds" - config "github.com/ipfs/go-ipfs/config" + "github.com/libp2p/go-libp2p-core/network" inet "github.com/libp2p/go-libp2p-core/network" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" + rcmgr "github.com/libp2p/go-libp2p-resource-manager" ma "github.com/multiformats/go-multiaddr" madns "github.com/multiformats/go-multiaddr-dns" mamask "github.com/whyrusleeping/multiaddr-filter" @@ -52,6 +59,8 @@ ipfs peers in the internet. "filters": swarmFiltersCmd, "peers": swarmPeersCmd, "peering": swarmPeeringCmd, + "stats": swarmStatsCmd, + "limit": swarmLimitCmd, }, } @@ -304,6 +313,403 @@ var swarmPeersCmd = &cmds.Command{ Type: connInfos{}, } +var swarmStatsCmd = &cmds.Command{ + Helptext: cmds.HelpText{ + Tagline: "Report resource usage for a scope.", + LongDescription: `Report resource usage for a scope. + The scope can be one of the following: + - system -- reports the system aggregate resource usage. + - transient -- reports the transient resource usage. + - svc: -- reports the resource usage of a specific service. + - proto: -- reports the resource usage of a specific protocol. + - peer: -- reports the resource usage of a specific peer. + - all -- reports the resource usage for all currently active scopes. +`}, + Arguments: []cmds.Argument{ + cmds.StringArg("scope", true, false, "scope of the stat report"), + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + node, err := cmdenv.GetNode(env) + if err != nil { + return err + } + + if node.ResourceManager == nil { + return fmt.Errorf("no resource manager available, make sure the daemon is running") + } + + if len(req.Arguments) != 1 { + return fmt.Errorf("must specify exactly one scope") + } + scope := req.Arguments[0] + result, err := NetStat(node.ResourceManager, req.Context, scope) + if err != nil { + return err + } + + b := new(bytes.Buffer) + enc := json.NewEncoder(b) + err = enc.Encode(result) + if err != nil { + return err + } + return cmds.EmitOnce(res, b) + }, +} + +var swarmLimitCmd = &cmds.Command{ + Helptext: cmds.HelpText{ + Tagline: "Get or set resource limits for a scope.", + LongDescription: `Get or set resource limits for a scope. + The scope can be one of the following: + - system -- reports the system aggregate resource usage. + - transient -- reports the transient resource usage. + - svc: -- reports the resource usage of a specific service. + - proto: -- reports the resource usage of a specific protocol. + - peer: -- reports the resource usage of a specific peer. + The limit is json-formatted, with the same structure as the limits file. +`}, + Arguments: []cmds.Argument{ + cmds.StringArg("scope", true, false, "scope of the limit"), + cmds.StringArg("limit", false, false, "path of the limit configuration file"), + }, + Options: []cmds.Option{ + cmds.BoolOption("set", "s", "Set the limit for a scope (instead of viewing it).").WithDefault(false), + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + node, err := cmdenv.GetNode(env) + if err != nil { + return err + } + + if node.ResourceManager == nil { + return fmt.Errorf("no resource manager available, make sure the daemon is running") + } + + setLimit, _ := req.Options["set"].(bool) + if setLimit { + if len(req.Arguments) != 2 { + return fmt.Errorf("must specify exactly a scope and a limit") + } + + scope := req.Arguments[0] + limitPath := req.Arguments[1] + limitStr, err := os.ReadFile(limitPath) + if err != nil { + return fmt.Errorf("error opening limit JSON file: %w", err) + } + + var limit NetLimitConfig + err = json.Unmarshal([]byte(limitStr), &limit) + if err != nil { + return fmt.Errorf("error decoding limit: %w", err) + } + + return NetSetLimit(node.ResourceManager, req.Context, scope, limit) + } + + if len(req.Arguments) != 1 { + return fmt.Errorf("must specify exactly one scope") + } + scope := req.Arguments[0] + result, err := NetLimit(node.ResourceManager, req.Context, scope) + if err != nil { + return err + } + + b := new(bytes.Buffer) + enc := json.NewEncoder(b) + err = enc.Encode(result) + if err != nil { + return err + } + return cmds.EmitOnce(res, b) + }, +} + +// FIXME(BLOCKING): Decide where to move the net stat/limit logic and types. + +type NetStatOut struct { + System *network.ScopeStat `json:",omitempty"` + Transient *network.ScopeStat `json:",omitempty"` + Services map[string]network.ScopeStat `json:",omitempty"` + Protocols map[string]network.ScopeStat `json:",omitempty"` + Peers map[string]network.ScopeStat `json:",omitempty"` +} + +type NetLimitConfig struct { + Dynamic bool `json:",omitempty"` + // set if Dynamic is false + Memory int64 `json:",omitempty"` + // set if Dynamic is true + MemoryFraction float64 `json:",omitempty"` + MinMemory int64 `json:",omitempty"` + MaxMemory int64 `json:",omitempty"` + + Streams, StreamsInbound, StreamsOutbound int + Conns, ConnsInbound, ConnsOutbound int + FD int +} + +func NetStat(mgr network.ResourceManager, ctx context.Context, scope string) (NetStatOut, error) { + var err error + var result NetStatOut + switch { + case scope == "all": + rapi, ok := mgr.(rcmgr.ResourceManagerState) + if !ok { + return result, fmt.Errorf("resource manager does not support ResourceManagerState API") + } + + stat := rapi.Stat() + result.System = &stat.System + result.Transient = &stat.Transient + if len(stat.Services) > 0 { + result.Services = stat.Services + } + if len(stat.Protocols) > 0 { + result.Protocols = make(map[string]network.ScopeStat, len(stat.Protocols)) + for proto, stat := range stat.Protocols { + result.Protocols[string(proto)] = stat + } + } + if len(stat.Peers) > 0 { + result.Peers = make(map[string]network.ScopeStat, len(stat.Peers)) + for p, stat := range stat.Peers { + result.Peers[p.Pretty()] = stat + } + } + + return result, nil + + case scope == "system": + err = mgr.ViewSystem(func(s network.ResourceScope) error { + stat := s.Stat() + result.System = &stat + return nil + }) + return result, err + + case scope == "transient": + err = mgr.ViewTransient(func(s network.ResourceScope) error { + stat := s.Stat() + result.Transient = &stat + return nil + }) + return result, err + + case strings.HasPrefix(scope, "svc:"): + svc := scope[4:] + err = mgr.ViewService(svc, func(s network.ServiceScope) error { + stat := s.Stat() + result.Services = map[string]network.ScopeStat{ + svc: stat, + } + return nil + }) + return result, err + + case strings.HasPrefix(scope, "proto:"): + proto := scope[6:] + err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { + stat := s.Stat() + result.Protocols = map[string]network.ScopeStat{ + proto: stat, + } + return nil + }) + return result, err + + case strings.HasPrefix(scope, "peer:"): + p := scope[5:] + pid, err := peer.Decode(p) + if err != nil { + return result, fmt.Errorf("invalid peer ID: %s: %w", p, err) + } + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { + stat := s.Stat() + result.Peers = map[string]network.ScopeStat{ + p: stat, + } + return nil + }) + return result, err + + default: + return result, fmt.Errorf("invalid scope %s", scope) + } +} + +func NetLimit(mgr network.ResourceManager, ctx context.Context, scope string) (NetLimitConfig, error) { + var result NetLimitConfig + getLimit := func(s network.ResourceScope) error { + limiter, ok := s.(rcmgr.ResourceScopeLimiter) + if !ok { + return fmt.Errorf("resource scope doesn't implement ResourceScopeLimiter interface") + } + + limit := limiter.Limit() + switch l := limit.(type) { + case *rcmgr.StaticLimit: + result.Memory = l.Memory + result.Streams = l.BaseLimit.Streams + result.StreamsInbound = l.BaseLimit.StreamsInbound + result.StreamsOutbound = l.BaseLimit.StreamsOutbound + result.Conns = l.BaseLimit.Conns + result.ConnsInbound = l.BaseLimit.ConnsInbound + result.ConnsOutbound = l.BaseLimit.ConnsOutbound + result.FD = l.BaseLimit.FD + + case *rcmgr.DynamicLimit: + result.Dynamic = true + result.MemoryFraction = l.MemoryLimit.MemoryFraction + result.MinMemory = l.MemoryLimit.MinMemory + result.MaxMemory = l.MemoryLimit.MaxMemory + result.Streams = l.BaseLimit.Streams + result.StreamsInbound = l.BaseLimit.StreamsInbound + result.StreamsOutbound = l.BaseLimit.StreamsOutbound + result.Conns = l.BaseLimit.Conns + result.ConnsInbound = l.BaseLimit.ConnsInbound + result.ConnsOutbound = l.BaseLimit.ConnsOutbound + result.FD = l.BaseLimit.FD + + default: + return fmt.Errorf("unknown limit type %T", limit) + } + + return nil + } + + switch { + case scope == "system": + err := mgr.ViewSystem(func(s network.ResourceScope) error { + return getLimit(s) + }) + return result, err + + case scope == "transient": + err := mgr.ViewTransient(func(s network.ResourceScope) error { + return getLimit(s) + }) + return result, err + + case strings.HasPrefix(scope, "svc:"): + svc := scope[4:] + err := mgr.ViewService(svc, func(s network.ServiceScope) error { + return getLimit(s) + }) + return result, err + + case strings.HasPrefix(scope, "proto:"): + proto := scope[6:] + err := mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { + return getLimit(s) + }) + return result, err + + case strings.HasPrefix(scope, "peer:"): + p := scope[5:] + pid, err := peer.Decode(p) + if err != nil { + return result, fmt.Errorf("invalid peer ID: %s: %w", p, err) + } + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { + return getLimit(s) + }) + return result, err + + default: + return result, fmt.Errorf("invalid scope %s", scope) + } +} + +func NetSetLimit(mgr network.ResourceManager, ctx context.Context, scope string, limit NetLimitConfig) error { + setLimit := func(s network.ResourceScope) error { + limiter, ok := s.(rcmgr.ResourceScopeLimiter) + if !ok { + return fmt.Errorf("resource scope doesn't implement ResourceScopeLimiter interface") + } + + var newLimit rcmgr.Limit + if limit.Dynamic { + newLimit = &rcmgr.DynamicLimit{ + MemoryLimit: rcmgr.MemoryLimit{ + MemoryFraction: limit.MemoryFraction, + MinMemory: limit.MinMemory, + MaxMemory: limit.MaxMemory, + }, + BaseLimit: rcmgr.BaseLimit{ + Streams: limit.Streams, + StreamsInbound: limit.StreamsInbound, + StreamsOutbound: limit.StreamsOutbound, + Conns: limit.Conns, + ConnsInbound: limit.ConnsInbound, + ConnsOutbound: limit.ConnsOutbound, + FD: limit.FD, + }, + } + } else { + newLimit = &rcmgr.StaticLimit{ + Memory: limit.Memory, + BaseLimit: rcmgr.BaseLimit{ + Streams: limit.Streams, + StreamsInbound: limit.StreamsInbound, + StreamsOutbound: limit.StreamsOutbound, + Conns: limit.Conns, + ConnsInbound: limit.ConnsInbound, + ConnsOutbound: limit.ConnsOutbound, + FD: limit.FD, + }, + } + } + + limiter.SetLimit(newLimit) + return nil + } + + switch { + case scope == "system": + err := mgr.ViewSystem(func(s network.ResourceScope) error { + return setLimit(s) + }) + return err + + case scope == "transient": + err := mgr.ViewTransient(func(s network.ResourceScope) error { + return setLimit(s) + }) + return err + + case strings.HasPrefix(scope, "svc:"): + svc := scope[4:] + err := mgr.ViewService(svc, func(s network.ServiceScope) error { + return setLimit(s) + }) + return err + + case strings.HasPrefix(scope, "proto:"): + proto := scope[6:] + err := mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { + return setLimit(s) + }) + return err + + case strings.HasPrefix(scope, "peer:"): + p := scope[5:] + pid, err := peer.Decode(p) + if err != nil { + return fmt.Errorf("invalid peer ID: %s: %w", p, err) + } + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { + return setLimit(s) + }) + return err + + default: + return fmt.Errorf("invalid scope %s", scope) + } +} + type streamInfo struct { Protocol string } diff --git a/core/core.go b/core/core.go index 888d3d78013..1a09b85e83f 100644 --- a/core/core.go +++ b/core/core.go @@ -30,6 +30,7 @@ import ( ic "github.com/libp2p/go-libp2p-core/crypto" p2phost "github.com/libp2p/go-libp2p-core/host" metrics "github.com/libp2p/go-libp2p-core/metrics" + "github.com/libp2p/go-libp2p-core/network" peer "github.com/libp2p/go-libp2p-core/peer" pstore "github.com/libp2p/go-libp2p-core/peerstore" routing "github.com/libp2p/go-libp2p-core/routing" @@ -85,17 +86,18 @@ type IpfsNode struct { RecordValidator record.Validator // Online - PeerHost p2phost.Host `optional:"true"` // the network host (server+client) - Peering *peering.PeeringService `optional:"true"` - Filters *ma.Filters `optional:"true"` - Bootstrapper io.Closer `optional:"true"` // the periodic bootstrapper - Routing routing.Routing `optional:"true"` // the routing system. recommend ipfs-dht - DNSResolver *madns.Resolver // the DNS resolver - Exchange exchange.Interface // the block exchange + strategy (bitswap) - Namesys namesys.NameSystem // the name system, resolves paths to hashes - Provider provider.System // the value provider system - IpnsRepub *ipnsrp.Republisher `optional:"true"` - GraphExchange graphsync.GraphExchange `optional:"true"` + PeerHost p2phost.Host `optional:"true"` // the network host (server+client) + Peering *peering.PeeringService `optional:"true"` + Filters *ma.Filters `optional:"true"` + Bootstrapper io.Closer `optional:"true"` // the periodic bootstrapper + Routing routing.Routing `optional:"true"` // the routing system. recommend ipfs-dht + DNSResolver *madns.Resolver // the DNS resolver + Exchange exchange.Interface // the block exchange + strategy (bitswap) + Namesys namesys.NameSystem // the name system, resolves paths to hashes + Provider provider.System // the value provider system + IpnsRepub *ipnsrp.Republisher `optional:"true"` + GraphExchange graphsync.GraphExchange `optional:"true"` + ResourceManager network.ResourceManager `optional:"true"` PubSub *pubsub.PubSub `optional:"true"` PSRouter *psrouter.PubsubValueStore `optional:"true"` diff --git a/core/node/groups.go b/core/node/groups.go index bca75c77df1..4d0f339195f 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -144,7 +144,9 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { opts := fx.Options( BaseLibP2P, + // Services (resource management) fx.Provide(libp2p.ResourceManager()), + fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), fx.Provide(libp2p.SmuxTransport(cfg.Swarm.Transports)), diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index dcd80dc4699..233bb9aeab0 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -1,40 +1,37 @@ package libp2p import ( - "errors" + "context" "fmt" - "os" - + "github.com/ipfs/go-ipfs/repo" "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p-core/network" rcmgr "github.com/libp2p/go-libp2p-resource-manager" + "go.uber.org/fx" ) -func ResourceManager() func() (Libp2pOpts, error) { - return func() (opts Libp2pOpts, err error) { +func ResourceManager() func(fx.Lifecycle, repo.Repo) (network.ResourceManager, Libp2pOpts, error) { + return func(lc fx.Lifecycle, repo repo.Repo) (network.ResourceManager, Libp2pOpts, error) { var limiter *rcmgr.BasicLimiter + var opts Libp2pOpts - limitsIn, err := os.Open("./limits.json") - switch { - case err == nil: - defer limitsIn.Close() - limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitsIn) - if err != nil { - return opts, fmt.Errorf("error parsing limit file: %w", err) - } - case errors.Is(err, os.ErrNotExist): - limiter = rcmgr.NewDefaultLimiter() - default: - return opts, err - } + // FIXME(BLOCKING): Decide how is the `limit.json` file path going to be consumed, + // either by default in the repo root or through the `go-ipfs-config`. + limiter = rcmgr.NewDefaultLimiter() libp2p.SetDefaultServiceLimits(limiter) - // TODO: close the resource manager when the node is shut down rcmgr, err := rcmgr.NewResourceManager(limiter) if err != nil { - return opts, fmt.Errorf("error creating resource manager: %w", err) + return nil, opts, fmt.Errorf("error creating resource manager: %w", err) } opts.Opts = append(opts.Opts, libp2p.ResourceManager(rcmgr)) - return opts, nil + + lc.Append(fx.Hook{ + OnStop: func(_ context.Context) error { + return rcmgr.Close() + }}) + + return rcmgr, opts, nil } } From 56457a16b496249dafd5c8231b717b1fbef25434 Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Mon, 7 Mar 2022 20:45:04 -0300 Subject: [PATCH 04/22] load limit file when building resource manager --- core/node/libp2p/rcmgr.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 233bb9aeab0..fc9e3a62d95 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -2,7 +2,9 @@ package libp2p import ( "context" + "errors" "fmt" + "os" "github.com/ipfs/go-ipfs/repo" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p-core/network" @@ -10,14 +12,28 @@ import ( "go.uber.org/fx" ) +const NetLimitDefaultFilename = "limit.json" + func ResourceManager() func(fx.Lifecycle, repo.Repo) (network.ResourceManager, Libp2pOpts, error) { return func(lc fx.Lifecycle, repo repo.Repo) (network.ResourceManager, Libp2pOpts, error) { var limiter *rcmgr.BasicLimiter var opts Libp2pOpts - // FIXME(BLOCKING): Decide how is the `limit.json` file path going to be consumed, - // either by default in the repo root or through the `go-ipfs-config`. - limiter = rcmgr.NewDefaultLimiter() + limitFile, err := os.Open(NetLimitDefaultFilename) + if errors.Is(err, os.ErrNotExist) { + limiter = rcmgr.NewDefaultLimiter() + } else { + if err != nil { + return nil, opts, fmt.Errorf("error opening limit JSON file %s: %w", + NetLimitDefaultFilename, err) + } + + defer limitFile.Close() //nolint:errcheck + limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitFile) + if err != nil { + return nil, opts, fmt.Errorf("error parsing limit file: %w", err) + } + } libp2p.SetDefaultServiceLimits(limiter) From 3efcb3d45a650672f0296bd762ad7999f57648aa Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Mon, 7 Mar 2022 20:55:38 -0300 Subject: [PATCH 05/22] log absent limit file --- core/node/libp2p/rcmgr.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index fc9e3a62d95..523731d6b1a 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -4,12 +4,12 @@ import ( "context" "errors" "fmt" - "os" "github.com/ipfs/go-ipfs/repo" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p-core/network" rcmgr "github.com/libp2p/go-libp2p-resource-manager" "go.uber.org/fx" + "os" ) const NetLimitDefaultFilename = "limit.json" @@ -21,6 +21,7 @@ func ResourceManager() func(fx.Lifecycle, repo.Repo) (network.ResourceManager, L limitFile, err := os.Open(NetLimitDefaultFilename) if errors.Is(err, os.ErrNotExist) { + log.Debug("limit file %s not found, creating a default resource manager", NetLimitDefaultFilename) limiter = rcmgr.NewDefaultLimiter() } else { if err != nil { From 761bbab0eb798544de69edc48a7a905ad1c480b6 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 11 Mar 2022 18:02:32 +0400 Subject: [PATCH 06/22] write rcmgr to file when IPFS_DEBUG_RCMGR is set --- core/node/libp2p/rcmgr.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 523731d6b1a..9d38dd958f3 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -4,12 +4,13 @@ import ( "context" "errors" "fmt" + "os" + "github.com/ipfs/go-ipfs/repo" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p-core/network" rcmgr "github.com/libp2p/go-libp2p-resource-manager" "go.uber.org/fx" - "os" ) const NetLimitDefaultFilename = "limit.json" @@ -38,7 +39,12 @@ func ResourceManager() func(fx.Lifecycle, repo.Repo) (network.ResourceManager, L libp2p.SetDefaultServiceLimits(limiter) - rcmgr, err := rcmgr.NewResourceManager(limiter) + var ropts []rcmgr.Option + if os.Getenv("IPFS_DEBUG_RCMGR") != "" { + ropts = append(ropts, rcmgr.WithTrace("rcmgr.json.gz")) + } + + rcmgr, err := rcmgr.NewResourceManager(limiter, ropts...) if err != nil { return nil, opts, fmt.Errorf("error creating resource manager: %w", err) } From bdac61f02c72e840115036fa9f24760f48fffd09 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 1 Apr 2022 21:21:04 +0200 Subject: [PATCH 07/22] fix: mark swarm limit|stats as experimental --- core/commands/swarm.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 7de6d3360c4..2d2a8b47b82 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -314,6 +314,7 @@ var swarmPeersCmd = &cmds.Command{ } var swarmStatsCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Report resource usage for a scope.", LongDescription: `Report resource usage for a scope. @@ -358,6 +359,7 @@ var swarmStatsCmd = &cmds.Command{ } var swarmLimitCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Get or set resource limits for a scope.", LongDescription: `Get or set resource limits for a scope. From 859e648fe1b440f061fda884f87e98b29b23135f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sat, 2 Apr 2022 01:56:19 +0200 Subject: [PATCH 08/22] feat(cfg): opt-in Swarm.ResourceMgr This ensures we can safely test the resource manager without impacting default behavior. - Resource manager is disabled by default - Default for Swarm.ResourceMgr.Enabled is false for now - Swarm.ResourceMgr.Limits allows user to tweak limits per specific scope in a way that is persisted across restarts - 'ipfs swarm limit system' outputs human-readable json - 'ipfs swarm limit system new-limits.json' sets new runtime limits (but does not change Swarm.ResourceMgr.Limits in the config) Conventions to make libp2p devs life easier: - 'IPFS_RCMGR=1 ipfs daemon' overrides the config and enables resource manager - 'limit.json' overrides implicit defaults from libp2p (if present) --- config/swarm.go | 36 ++++ core/commands/config.go | 20 +- core/commands/swarm.go | 387 ++++++-------------------------------- core/node/groups.go | 2 +- core/node/libp2p/rcmgr.go | 356 ++++++++++++++++++++++++++++++++--- docs/config.md | 69 +++++++ 6 files changed, 505 insertions(+), 365 deletions(-) diff --git a/config/swarm.go b/config/swarm.go index ba7b2255fd5..a18a2fd5dae 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -49,6 +49,9 @@ type SwarmConfig struct { // ConnMgr configures the connection manager. ConnMgr ConnMgr + + // ResourceMgr configures the libp2p Network Resource Manager + ResourceMgr ResourceMgr } type RelayClient struct { @@ -129,3 +132,36 @@ type ConnMgr struct { HighWater int GracePeriod string } + +// ResourceMgr defines configuration options for the libp2p Network Resource Manager +// +type ResourceMgr struct { + // Enables the Network Resource Manager feature + Enabled Flag `json:",omitempty"` + + // Limits is a map of Resource Scope. + Limits map[string]ResourceMgrScopeConfig `json:",omitempty"` +} + +const ( + ResourceMgrSystemScope = "system" + ResourceMgrTransientScope = "transient" + ResourceMgrServiceScopePrefix = "svc:" + ResourceMgrProtocolScopePrefix = "proto:" + ResourceMgrPeerScopePrefix = "peer:" +) + +// libp2p Network Resource Manager config for a scope (ipfs swarm stats|limit) +type ResourceMgrScopeConfig struct { + Dynamic bool `json:",omitempty"` + // set if Dynamic is false + Memory int64 `json:",omitempty"` + // set if Dynamic is true + MemoryFraction float64 `json:",omitempty"` + MinMemory int64 `json:",omitempty"` + MaxMemory int64 `json:",omitempty"` + + Streams, StreamsInbound, StreamsOutbound int + Conns, ConnsInbound, ConnsOutbound int + FD int +} diff --git a/core/commands/config.go b/core/commands/config.go index 7a6e5abaf07..7c4ae78f12a 100644 --- a/core/commands/config.go +++ b/core/commands/config.go @@ -215,18 +215,20 @@ NOTE: For security reasons, this command will omit your private key and remote s return cmds.EmitOnce(res, &cfg) }, Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *map[string]interface{}) error { - buf, err := config.HumanOutput(out) - if err != nil { - return err - } - buf = append(buf, byte('\n')) - _, err = w.Write(buf) - return err - }), + cmds.Text: HumanJsonEncoder, }, } +var HumanJsonEncoder = cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *map[string]interface{}) error { + buf, err := config.HumanOutput(out) + if err != nil { + return err + } + buf = append(buf, byte('\n')) + _, err = w.Write(buf) + return err +}) + // Scrubs value and returns error if missing func scrubValue(m map[string]interface{}, key []string) (map[string]interface{}, error) { return scrubMapInternal(m, key, false) diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 2d2a8b47b82..b82ca519a03 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -7,25 +7,22 @@ import ( "errors" "fmt" "io" - "os" "path" "sort" - "strings" "sync" "time" + files "github.com/ipfs/go-ipfs-files" "github.com/ipfs/go-ipfs/commands" "github.com/ipfs/go-ipfs/config" "github.com/ipfs/go-ipfs/core/commands/cmdenv" + "github.com/ipfs/go-ipfs/core/node/libp2p" "github.com/ipfs/go-ipfs/repo" "github.com/ipfs/go-ipfs/repo/fsrepo" cmds "github.com/ipfs/go-ipfs-cmds" - "github.com/libp2p/go-libp2p-core/network" inet "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" - rcmgr "github.com/libp2p/go-libp2p-resource-manager" ma "github.com/multiformats/go-multiaddr" madns "github.com/multiformats/go-multiaddr-dns" mamask "github.com/whyrusleeping/multiaddr-filter" @@ -59,8 +56,8 @@ ipfs peers in the internet. "filters": swarmFiltersCmd, "peers": swarmPeersCmd, "peering": swarmPeeringCmd, - "stats": swarmStatsCmd, - "limit": swarmLimitCmd, + "stats": swarmStatsCmd, // libp2p Network Resource Manager + "limit": swarmLimitCmd, // libp2p Network Resource Manager }, } @@ -318,13 +315,15 @@ var swarmStatsCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Report resource usage for a scope.", LongDescription: `Report resource usage for a scope. - The scope can be one of the following: - - system -- reports the system aggregate resource usage. - - transient -- reports the transient resource usage. - - svc: -- reports the resource usage of a specific service. - - proto: -- reports the resource usage of a specific protocol. - - peer: -- reports the resource usage of a specific peer. - - all -- reports the resource usage for all currently active scopes. +The scope can be one of the following: +- system -- reports the system aggregate resource usage. +- transient -- reports the transient resource usage. +- svc: -- reports the resource usage of a specific service. +- proto: -- reports the resource usage of a specific protocol. +- peer: -- reports the resource usage of a specific peer. +- all -- reports the resource usage for all currently active scopes. + +The output of this command is JSON. `}, Arguments: []cmds.Argument{ cmds.StringArg("scope", true, false, "scope of the stat report"), @@ -343,7 +342,7 @@ var swarmStatsCmd = &cmds.Command{ return fmt.Errorf("must specify exactly one scope") } scope := req.Arguments[0] - result, err := NetStat(node.ResourceManager, req.Context, scope) + result, err := libp2p.NetStat(node.ResourceManager, scope) if err != nil { return err } @@ -356,6 +355,9 @@ var swarmStatsCmd = &cmds.Command{ } return cmds.EmitOnce(res, b) }, + Encoders: cmds.EncoderMap{ + cmds.Text: HumanJsonEncoder, + }, } var swarmLimitCmd = &cmds.Command{ @@ -363,20 +365,27 @@ var swarmLimitCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Get or set resource limits for a scope.", LongDescription: `Get or set resource limits for a scope. - The scope can be one of the following: - - system -- reports the system aggregate resource usage. - - transient -- reports the transient resource usage. - - svc: -- reports the resource usage of a specific service. - - proto: -- reports the resource usage of a specific protocol. - - peer: -- reports the resource usage of a specific peer. - The limit is json-formatted, with the same structure as the limits file. +The scope can be one of the following: +- system -- limits for the system aggregate resource usage. +- transient -- limits for the transient resource usage. +- svc: -- limits for the resource usage of a specific service. +- proto: -- limits for the resource usage of a specific protocol. +- peer: -- limits for the resource usage of a specific peer. + +The output of this command is JSON. + +It is possible to use this command to inspect and tweak limits at runtime: + + $ ipfs swarm limit system > limit.json + $ vi limit.json + $ ipfs swarm limit system limit.json + +Changes made via command line are discarded on node shutdown. +For permanent limits set Swarm.ResourceMgr.Limits in the $IPFS_PATH/config file. `}, Arguments: []cmds.Argument{ cmds.StringArg("scope", true, false, "scope of the limit"), - cmds.StringArg("limit", false, false, "path of the limit configuration file"), - }, - Options: []cmds.Option{ - cmds.BoolOption("set", "s", "Set the limit for a scope (instead of viewing it).").WithDefault(false), + cmds.FileArg("limit.json", false, false, "limits to be set").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { node, err := cmdenv.GetNode(env) @@ -388,33 +397,29 @@ var swarmLimitCmd = &cmds.Command{ return fmt.Errorf("no resource manager available, make sure the daemon is running") } - setLimit, _ := req.Options["set"].(bool) - if setLimit { - if len(req.Arguments) != 2 { - return fmt.Errorf("must specify exactly a scope and a limit") - } + scope := req.Arguments[0] - scope := req.Arguments[0] - limitPath := req.Arguments[1] - limitStr, err := os.ReadFile(limitPath) - if err != nil { - return fmt.Errorf("error opening limit JSON file: %w", err) + // set scope limit to new values (when limit.json is passed as a second arg) + if req.Files != nil { + var newLimit config.ResourceMgrScopeConfig + it := req.Files.Entries() + if it.Next() { + file := files.FileFromEntry(it) + if file == nil { + return errors.New("expected a JSON file") + } + if err := json.NewDecoder(file).Decode(&newLimit); err != nil { + return errors.New("failed to decode JSON as ResourceMgrScopeConfig") + } + return libp2p.NetSetLimit(node.ResourceManager, scope, newLimit) } - - var limit NetLimitConfig - err = json.Unmarshal([]byte(limitStr), &limit) - if err != nil { - return fmt.Errorf("error decoding limit: %w", err) + if err := it.Err(); err != nil { + return fmt.Errorf("error opening limit JSON file: %w", err) } - - return NetSetLimit(node.ResourceManager, req.Context, scope, limit) } - if len(req.Arguments) != 1 { - return fmt.Errorf("must specify exactly one scope") - } - scope := req.Arguments[0] - result, err := NetLimit(node.ResourceManager, req.Context, scope) + // get scope limit + result, err := libp2p.NetLimit(node.ResourceManager, scope) if err != nil { return err } @@ -427,289 +432,9 @@ var swarmLimitCmd = &cmds.Command{ } return cmds.EmitOnce(res, b) }, -} - -// FIXME(BLOCKING): Decide where to move the net stat/limit logic and types. - -type NetStatOut struct { - System *network.ScopeStat `json:",omitempty"` - Transient *network.ScopeStat `json:",omitempty"` - Services map[string]network.ScopeStat `json:",omitempty"` - Protocols map[string]network.ScopeStat `json:",omitempty"` - Peers map[string]network.ScopeStat `json:",omitempty"` -} - -type NetLimitConfig struct { - Dynamic bool `json:",omitempty"` - // set if Dynamic is false - Memory int64 `json:",omitempty"` - // set if Dynamic is true - MemoryFraction float64 `json:",omitempty"` - MinMemory int64 `json:",omitempty"` - MaxMemory int64 `json:",omitempty"` - - Streams, StreamsInbound, StreamsOutbound int - Conns, ConnsInbound, ConnsOutbound int - FD int -} - -func NetStat(mgr network.ResourceManager, ctx context.Context, scope string) (NetStatOut, error) { - var err error - var result NetStatOut - switch { - case scope == "all": - rapi, ok := mgr.(rcmgr.ResourceManagerState) - if !ok { - return result, fmt.Errorf("resource manager does not support ResourceManagerState API") - } - - stat := rapi.Stat() - result.System = &stat.System - result.Transient = &stat.Transient - if len(stat.Services) > 0 { - result.Services = stat.Services - } - if len(stat.Protocols) > 0 { - result.Protocols = make(map[string]network.ScopeStat, len(stat.Protocols)) - for proto, stat := range stat.Protocols { - result.Protocols[string(proto)] = stat - } - } - if len(stat.Peers) > 0 { - result.Peers = make(map[string]network.ScopeStat, len(stat.Peers)) - for p, stat := range stat.Peers { - result.Peers[p.Pretty()] = stat - } - } - - return result, nil - - case scope == "system": - err = mgr.ViewSystem(func(s network.ResourceScope) error { - stat := s.Stat() - result.System = &stat - return nil - }) - return result, err - - case scope == "transient": - err = mgr.ViewTransient(func(s network.ResourceScope) error { - stat := s.Stat() - result.Transient = &stat - return nil - }) - return result, err - - case strings.HasPrefix(scope, "svc:"): - svc := scope[4:] - err = mgr.ViewService(svc, func(s network.ServiceScope) error { - stat := s.Stat() - result.Services = map[string]network.ScopeStat{ - svc: stat, - } - return nil - }) - return result, err - - case strings.HasPrefix(scope, "proto:"): - proto := scope[6:] - err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { - stat := s.Stat() - result.Protocols = map[string]network.ScopeStat{ - proto: stat, - } - return nil - }) - return result, err - - case strings.HasPrefix(scope, "peer:"): - p := scope[5:] - pid, err := peer.Decode(p) - if err != nil { - return result, fmt.Errorf("invalid peer ID: %s: %w", p, err) - } - err = mgr.ViewPeer(pid, func(s network.PeerScope) error { - stat := s.Stat() - result.Peers = map[string]network.ScopeStat{ - p: stat, - } - return nil - }) - return result, err - - default: - return result, fmt.Errorf("invalid scope %s", scope) - } -} - -func NetLimit(mgr network.ResourceManager, ctx context.Context, scope string) (NetLimitConfig, error) { - var result NetLimitConfig - getLimit := func(s network.ResourceScope) error { - limiter, ok := s.(rcmgr.ResourceScopeLimiter) - if !ok { - return fmt.Errorf("resource scope doesn't implement ResourceScopeLimiter interface") - } - - limit := limiter.Limit() - switch l := limit.(type) { - case *rcmgr.StaticLimit: - result.Memory = l.Memory - result.Streams = l.BaseLimit.Streams - result.StreamsInbound = l.BaseLimit.StreamsInbound - result.StreamsOutbound = l.BaseLimit.StreamsOutbound - result.Conns = l.BaseLimit.Conns - result.ConnsInbound = l.BaseLimit.ConnsInbound - result.ConnsOutbound = l.BaseLimit.ConnsOutbound - result.FD = l.BaseLimit.FD - - case *rcmgr.DynamicLimit: - result.Dynamic = true - result.MemoryFraction = l.MemoryLimit.MemoryFraction - result.MinMemory = l.MemoryLimit.MinMemory - result.MaxMemory = l.MemoryLimit.MaxMemory - result.Streams = l.BaseLimit.Streams - result.StreamsInbound = l.BaseLimit.StreamsInbound - result.StreamsOutbound = l.BaseLimit.StreamsOutbound - result.Conns = l.BaseLimit.Conns - result.ConnsInbound = l.BaseLimit.ConnsInbound - result.ConnsOutbound = l.BaseLimit.ConnsOutbound - result.FD = l.BaseLimit.FD - - default: - return fmt.Errorf("unknown limit type %T", limit) - } - - return nil - } - - switch { - case scope == "system": - err := mgr.ViewSystem(func(s network.ResourceScope) error { - return getLimit(s) - }) - return result, err - - case scope == "transient": - err := mgr.ViewTransient(func(s network.ResourceScope) error { - return getLimit(s) - }) - return result, err - - case strings.HasPrefix(scope, "svc:"): - svc := scope[4:] - err := mgr.ViewService(svc, func(s network.ServiceScope) error { - return getLimit(s) - }) - return result, err - - case strings.HasPrefix(scope, "proto:"): - proto := scope[6:] - err := mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { - return getLimit(s) - }) - return result, err - - case strings.HasPrefix(scope, "peer:"): - p := scope[5:] - pid, err := peer.Decode(p) - if err != nil { - return result, fmt.Errorf("invalid peer ID: %s: %w", p, err) - } - err = mgr.ViewPeer(pid, func(s network.PeerScope) error { - return getLimit(s) - }) - return result, err - - default: - return result, fmt.Errorf("invalid scope %s", scope) - } -} - -func NetSetLimit(mgr network.ResourceManager, ctx context.Context, scope string, limit NetLimitConfig) error { - setLimit := func(s network.ResourceScope) error { - limiter, ok := s.(rcmgr.ResourceScopeLimiter) - if !ok { - return fmt.Errorf("resource scope doesn't implement ResourceScopeLimiter interface") - } - - var newLimit rcmgr.Limit - if limit.Dynamic { - newLimit = &rcmgr.DynamicLimit{ - MemoryLimit: rcmgr.MemoryLimit{ - MemoryFraction: limit.MemoryFraction, - MinMemory: limit.MinMemory, - MaxMemory: limit.MaxMemory, - }, - BaseLimit: rcmgr.BaseLimit{ - Streams: limit.Streams, - StreamsInbound: limit.StreamsInbound, - StreamsOutbound: limit.StreamsOutbound, - Conns: limit.Conns, - ConnsInbound: limit.ConnsInbound, - ConnsOutbound: limit.ConnsOutbound, - FD: limit.FD, - }, - } - } else { - newLimit = &rcmgr.StaticLimit{ - Memory: limit.Memory, - BaseLimit: rcmgr.BaseLimit{ - Streams: limit.Streams, - StreamsInbound: limit.StreamsInbound, - StreamsOutbound: limit.StreamsOutbound, - Conns: limit.Conns, - ConnsInbound: limit.ConnsInbound, - ConnsOutbound: limit.ConnsOutbound, - FD: limit.FD, - }, - } - } - - limiter.SetLimit(newLimit) - return nil - } - - switch { - case scope == "system": - err := mgr.ViewSystem(func(s network.ResourceScope) error { - return setLimit(s) - }) - return err - - case scope == "transient": - err := mgr.ViewTransient(func(s network.ResourceScope) error { - return setLimit(s) - }) - return err - - case strings.HasPrefix(scope, "svc:"): - svc := scope[4:] - err := mgr.ViewService(svc, func(s network.ServiceScope) error { - return setLimit(s) - }) - return err - - case strings.HasPrefix(scope, "proto:"): - proto := scope[6:] - err := mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { - return setLimit(s) - }) - return err - - case strings.HasPrefix(scope, "peer:"): - p := scope[5:] - pid, err := peer.Decode(p) - if err != nil { - return fmt.Errorf("invalid peer ID: %s: %w", p, err) - } - err = mgr.ViewPeer(pid, func(s network.PeerScope) error { - return setLimit(s) - }) - return err - - default: - return fmt.Errorf("invalid scope %s", scope) - } + Encoders: cmds.EncoderMap{ + cmds.Text: HumanJsonEncoder, + }, } type streamInfo struct { diff --git a/core/node/groups.go b/core/node/groups.go index 4d0f339195f..48ee175a33c 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -145,7 +145,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { BaseLibP2P, // Services (resource management) - fx.Provide(libp2p.ResourceManager()), + fx.Provide(libp2p.ResourceManager(cfg.Swarm.ResourceMgr)), fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 9d38dd958f3..c4af75ae142 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -5,56 +5,364 @@ import ( "errors" "fmt" "os" + "strings" + cfg "github.com/ipfs/go-ipfs/config" + config "github.com/ipfs/go-ipfs/config" "github.com/ipfs/go-ipfs/repo" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" rcmgr "github.com/libp2p/go-libp2p-resource-manager" "go.uber.org/fx" ) const NetLimitDefaultFilename = "limit.json" -func ResourceManager() func(fx.Lifecycle, repo.Repo) (network.ResourceManager, Libp2pOpts, error) { +func ResourceManager(cfg cfg.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network.ResourceManager, Libp2pOpts, error) { return func(lc fx.Lifecycle, repo repo.Repo) (network.ResourceManager, Libp2pOpts, error) { var limiter *rcmgr.BasicLimiter + var manager network.ResourceManager var opts Libp2pOpts - limitFile, err := os.Open(NetLimitDefaultFilename) - if errors.Is(err, os.ErrNotExist) { - log.Debug("limit file %s not found, creating a default resource manager", NetLimitDefaultFilename) - limiter = rcmgr.NewDefaultLimiter() - } else { - if err != nil { - return nil, opts, fmt.Errorf("error opening limit JSON file %s: %w", - NetLimitDefaultFilename, err) + // Config Swarm.ResourceMgr.Enabled decides if we run a real manager + enabled := cfg.Enabled.WithDefault(false) + + /// ENV overrides Config (if present) + // TODO: document IPFS_RCMGR and IPFS_DEBUG_RCMGR in docs/environment-variables.md + switch os.Getenv("IPFS_RCMGR") { + case "0", "false": + enabled = false + case "1", "true": + enabled = true + } + + if enabled { + log.Debug("libp2p resource manager is enabled") + + // Try defaults from limit.json if provided + // (a convention to make libp2p team life easier) + // TODO: look in current dir and in IPFS_PATH + _, err := os.Stat(NetLimitDefaultFilename) + if !errors.Is(err, os.ErrNotExist) { + limitFile, err := os.Open(NetLimitDefaultFilename) + if err != nil { + return nil, opts, fmt.Errorf("error opening limit JSON file %s: %w", + NetLimitDefaultFilename, err) + } + defer limitFile.Close() //nolint:errcheck + limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitFile) + if err != nil { + return nil, opts, fmt.Errorf("error parsing limit file: %w", err) + } + + } else { + // Use defaults from go-libp2p + log.Debug("limit file %s not found, creating a default resource manager", NetLimitDefaultFilename) + limiter = rcmgr.NewDefaultLimiter() + } + + libp2p.SetDefaultServiceLimits(limiter) + + var ropts []rcmgr.Option + if os.Getenv("IPFS_DEBUG_RCMGR") != "" { + ropts = append(ropts, rcmgr.WithTrace("rcmgr.json.gz")) } - defer limitFile.Close() //nolint:errcheck - limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitFile) + manager, err = rcmgr.NewResourceManager(limiter, ropts...) if err != nil { - return nil, opts, fmt.Errorf("error parsing limit file: %w", err) + return nil, opts, fmt.Errorf("error creating resource manager: %w", err) } - } - libp2p.SetDefaultServiceLimits(limiter) + // Apply user-defined Swarm.ResourceMgr.Limits + for scope, userLimit := range cfg.Limits { + err := NetSetLimit(manager, scope, userLimit) + if err != nil { + return nil, opts, fmt.Errorf("error while applying Swarm.ResourceMgr.Limits for scope %q: %w", scope, err) + } + } - var ropts []rcmgr.Option - if os.Getenv("IPFS_DEBUG_RCMGR") != "" { - ropts = append(ropts, rcmgr.WithTrace("rcmgr.json.gz")) + } else { + log.Debug("libp2p resource manager is disabled") + manager = network.NullResourceManager } - rcmgr, err := rcmgr.NewResourceManager(limiter, ropts...) - if err != nil { - return nil, opts, fmt.Errorf("error creating resource manager: %w", err) - } - opts.Opts = append(opts.Opts, libp2p.ResourceManager(rcmgr)) + opts.Opts = append(opts.Opts, libp2p.ResourceManager(manager)) lc.Append(fx.Hook{ OnStop: func(_ context.Context) error { - return rcmgr.Close() + return manager.Close() }}) - return rcmgr, opts, nil + return manager, opts, nil + } +} + +type NetStatOut struct { + System *network.ScopeStat `json:",omitempty"` + Transient *network.ScopeStat `json:",omitempty"` + Services map[string]network.ScopeStat `json:",omitempty"` + Protocols map[string]network.ScopeStat `json:",omitempty"` + Peers map[string]network.ScopeStat `json:",omitempty"` +} + +func NetStat(mgr network.ResourceManager, scope string) (NetStatOut, error) { + var err error + var result NetStatOut + switch { + case scope == "all": + rapi, ok := mgr.(rcmgr.ResourceManagerState) + if !ok { + return result, fmt.Errorf("resource manager does not support ResourceManagerState API") + } + + stat := rapi.Stat() + result.System = &stat.System + result.Transient = &stat.Transient + if len(stat.Services) > 0 { + result.Services = stat.Services + } + if len(stat.Protocols) > 0 { + result.Protocols = make(map[string]network.ScopeStat, len(stat.Protocols)) + for proto, stat := range stat.Protocols { + result.Protocols[string(proto)] = stat + } + } + if len(stat.Peers) > 0 { + result.Peers = make(map[string]network.ScopeStat, len(stat.Peers)) + for p, stat := range stat.Peers { + result.Peers[p.Pretty()] = stat + } + } + + return result, nil + + case scope == config.ResourceMgrSystemScope: + err = mgr.ViewSystem(func(s network.ResourceScope) error { + stat := s.Stat() + result.System = &stat + return nil + }) + return result, err + + case scope == config.ResourceMgrTransientScope: + err = mgr.ViewTransient(func(s network.ResourceScope) error { + stat := s.Stat() + result.Transient = &stat + return nil + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): + svc := scope[4:] + err = mgr.ViewService(svc, func(s network.ServiceScope) error { + stat := s.Stat() + result.Services = map[string]network.ScopeStat{ + svc: stat, + } + return nil + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): + proto := scope[6:] + err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { + stat := s.Stat() + result.Protocols = map[string]network.ScopeStat{ + proto: stat, + } + return nil + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): + p := scope[5:] + pid, err := peer.Decode(p) + if err != nil { + return result, fmt.Errorf("invalid peer ID: %q: %w", p, err) + } + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { + stat := s.Stat() + result.Peers = map[string]network.ScopeStat{ + p: stat, + } + return nil + }) + return result, err + + default: + return result, fmt.Errorf("invalid scope %q", scope) + } +} + +func NetLimit(mgr network.ResourceManager, scope string) (config.ResourceMgrScopeConfig, error) { + var result config.ResourceMgrScopeConfig + getLimit := func(s network.ResourceScope) error { + limiter, ok := s.(rcmgr.ResourceScopeLimiter) + if !ok { + return fmt.Errorf("resource scope doesn't implement ResourceScopeLimiter interface") + } + + limit := limiter.Limit() + switch l := limit.(type) { + case *rcmgr.StaticLimit: + result.Dynamic = false + result.Memory = l.Memory + result.Streams = l.BaseLimit.Streams + result.StreamsInbound = l.BaseLimit.StreamsInbound + result.StreamsOutbound = l.BaseLimit.StreamsOutbound + result.Conns = l.BaseLimit.Conns + result.ConnsInbound = l.BaseLimit.ConnsInbound + result.ConnsOutbound = l.BaseLimit.ConnsOutbound + result.FD = l.BaseLimit.FD + + case *rcmgr.DynamicLimit: + result.Dynamic = true + result.MemoryFraction = l.MemoryLimit.MemoryFraction + result.MinMemory = l.MemoryLimit.MinMemory + result.MaxMemory = l.MemoryLimit.MaxMemory + result.Streams = l.BaseLimit.Streams + result.StreamsInbound = l.BaseLimit.StreamsInbound + result.StreamsOutbound = l.BaseLimit.StreamsOutbound + result.Conns = l.BaseLimit.Conns + result.ConnsInbound = l.BaseLimit.ConnsInbound + result.ConnsOutbound = l.BaseLimit.ConnsOutbound + result.FD = l.BaseLimit.FD + + default: + return fmt.Errorf("unknown limit type %T", limit) + } + + return nil + } + + switch { + case scope == config.ResourceMgrSystemScope: + err := mgr.ViewSystem(func(s network.ResourceScope) error { + return getLimit(s) + }) + return result, err + + case scope == config.ResourceMgrTransientScope: + err := mgr.ViewTransient(func(s network.ResourceScope) error { + return getLimit(s) + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): + svc := scope[4:] + err := mgr.ViewService(svc, func(s network.ServiceScope) error { + return getLimit(s) + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): + proto := scope[6:] + err := mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { + return getLimit(s) + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): + p := scope[5:] + pid, err := peer.Decode(p) + if err != nil { + return result, fmt.Errorf("invalid peer ID: %q: %w", p, err) + } + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { + return getLimit(s) + }) + return result, err + + default: + return result, fmt.Errorf("invalid scope %q", scope) + } +} + +func NetSetLimit(mgr network.ResourceManager, scope string, limit config.ResourceMgrScopeConfig) error { + setLimit := func(s network.ResourceScope) error { + limiter, ok := s.(rcmgr.ResourceScopeLimiter) + if !ok { + return fmt.Errorf("resource scope doesn't implement ResourceScopeLimiter interface") + } + + var newLimit rcmgr.Limit + if limit.Dynamic { + newLimit = &rcmgr.DynamicLimit{ + MemoryLimit: rcmgr.MemoryLimit{ + MemoryFraction: limit.MemoryFraction, + MinMemory: limit.MinMemory, + MaxMemory: limit.MaxMemory, + }, + BaseLimit: rcmgr.BaseLimit{ + Streams: limit.Streams, + StreamsInbound: limit.StreamsInbound, + StreamsOutbound: limit.StreamsOutbound, + Conns: limit.Conns, + ConnsInbound: limit.ConnsInbound, + ConnsOutbound: limit.ConnsOutbound, + FD: limit.FD, + }, + } + } else { + newLimit = &rcmgr.StaticLimit{ + Memory: limit.Memory, + BaseLimit: rcmgr.BaseLimit{ + Streams: limit.Streams, + StreamsInbound: limit.StreamsInbound, + StreamsOutbound: limit.StreamsOutbound, + Conns: limit.Conns, + ConnsInbound: limit.ConnsInbound, + ConnsOutbound: limit.ConnsOutbound, + FD: limit.FD, + }, + } + } + + limiter.SetLimit(newLimit) + return nil + } + + switch { + case scope == config.ResourceMgrSystemScope: + err := mgr.ViewSystem(func(s network.ResourceScope) error { + return setLimit(s) + }) + return err + + case scope == config.ResourceMgrTransientScope: + err := mgr.ViewTransient(func(s network.ResourceScope) error { + return setLimit(s) + }) + return err + + case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): + svc := scope[4:] + err := mgr.ViewService(svc, func(s network.ServiceScope) error { + return setLimit(s) + }) + return err + + case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): + proto := scope[6:] + err := mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { + return setLimit(s) + }) + return err + + case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): + p := scope[5:] + pid, err := peer.Decode(p) + if err != nil { + return fmt.Errorf("invalid peer ID: %q: %w", p, err) + } + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { + return setLimit(s) + }) + return err + + default: + return fmt.Errorf("invalid scope %q", scope) } } diff --git a/docs/config.md b/docs/config.md index 2c935190923..34845379707 100644 --- a/docs/config.md +++ b/docs/config.md @@ -130,6 +130,7 @@ config file at runtime. - [`Swarm.ConnMgr.LowWater`](#swarmconnmgrlowwater) - [`Swarm.ConnMgr.HighWater`](#swarmconnmgrhighwater) - [`Swarm.ConnMgr.GracePeriod`](#swarmconnmgrgraceperiod) + - [`Swarm.ResourceMgr`](#swarmresourcemgr) - [`Swarm.Transports`](#swarmtransports) - [`Swarm.Transports.Network`](#swarmtransportsnetwork) - [`Swarm.Transports.Network.TCP`](#swarmtransportsnetworktcp) @@ -1628,6 +1629,74 @@ Default: `"20s"` Type: `duration` +### `Swarm.ResourceMgr` + +The [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) allows setting limits per a scope, +and track recource usage over time. + +#### `Swarm.ResourceMgr.Enabled` + +**EXPERIMENTAL**: this feature is is disabled by default, use with caution. + +Enables the libp2p Network Resource Manager and auguments the default limits +using user-defined ones in `Swarm.ResourceMgr.Limits` (if present). + +Default: `false` + +Type: `flag` + +#### `Swarm.ResourceMgr.Limits` + +Map of resource limits [per scope](https://github.com/libp2p/go-libp2p-resource-manager#resource-scopes). + +The key is a string with the scope name. It can be one of the following: +- `system` -- limits the system aggregate resource usage. +- `transient` -- limits the transient resource usage +- `svc:` -- limits the resource usage of a specific service +- `proto:` -- limits the resource usage of a specific protocol +- `peer:` -- limits the resource usage of a specific peer + +Example: + +```json +{ + "Swarm": { + "ResourceMgr": { + "Enabled": true, + "Limits": { + "system": { + "Conns": 1024, + "ConnsInbound": 256, + "ConnsOutbound": 1024, + "FD": 512, + "Memory": 1073741824, + "Streams": 16384, + "StreamsInbound": 4096, + "StreamsOutbound": 16384 + }, + "transient": { + "Conns": 128, + "ConnsInbound": 32, + "ConnsOutbound": 128, + "FD": 128, + "Memory": 67108864, + "Streams": 512, + "StreamsInbound": 128, + "StreamsOutbound": 512 + } + } + } + } +} +``` + +Current resource usage and a list of services, protocols, and peers can be obtained via +`ipfs swarm stats --help` + +Default: `{}` (empty == implicit defaults from go-libp2p) + +Type: `object[string->object] + ### `Swarm.Transports` Configuration section for libp2p transports. An empty configuration will apply From cb511e13c7e7a3040f2e20fc9f53b19d23fa4f34 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sat, 2 Apr 2022 03:04:49 +0200 Subject: [PATCH 09/22] docs(config): small tweaks --- docs/config.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index 34845379707..8a17dc9880d 100644 --- a/docs/config.md +++ b/docs/config.md @@ -131,6 +131,8 @@ config file at runtime. - [`Swarm.ConnMgr.HighWater`](#swarmconnmgrhighwater) - [`Swarm.ConnMgr.GracePeriod`](#swarmconnmgrgraceperiod) - [`Swarm.ResourceMgr`](#swarmresourcemgr) + - [`Swarm.ResourceMgr.Enabled`](#swarmresourcemgrenabled) + - [`Swarm.ResourceMgr.Limits`](#swarmresourcemgrlimits) - [`Swarm.Transports`](#swarmtransports) - [`Swarm.Transports.Network`](#swarmtransportsnetwork) - [`Swarm.Transports.Network.TCP`](#swarmtransportsnetworktcp) @@ -1693,9 +1695,13 @@ Example: Current resource usage and a list of services, protocols, and peers can be obtained via `ipfs swarm stats --help` +It is also possible to adjust runtime limits via `ipfs stats limit --help`, +however changes are ephemeral (config remains intact), and won't be applied +after reboot. + Default: `{}` (empty == implicit defaults from go-libp2p) -Type: `object[string->object] +Type: `object[string->object]` ### `Swarm.Transports` From b19f7c9eca4cee4187f8cba3389dc2c930258512 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sat, 2 Apr 2022 03:13:15 +0200 Subject: [PATCH 10/22] fix: skip libp2p.ResourceManager if disabled This ensures 'ipfs swarm limit|stats' work only when enabled. --- core/commands/swarm.go | 2 +- core/node/groups.go | 13 +++++- core/node/libp2p/rcmgr.go | 88 ++++++++++++++++----------------------- 3 files changed, 48 insertions(+), 55 deletions(-) diff --git a/core/commands/swarm.go b/core/commands/swarm.go index b82ca519a03..a213db6f74f 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -394,7 +394,7 @@ For permanent limits set Swarm.ResourceMgr.Limits in the $IPFS_PATH/config file. } if node.ResourceManager == nil { - return fmt.Errorf("no resource manager available, make sure the daemon is running") + return fmt.Errorf("no resource manager available: make sure the daemon is running with Swarm.ResourceMgr.Enabled in the config") } scope := req.Arguments[0] diff --git a/core/node/groups.go b/core/node/groups.go index 48ee175a33c..992c9ab446a 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "os" "time" blockstore "github.com/ipfs/go-ipfs-blockstore" @@ -140,12 +141,22 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { "If you want to continue running a circuit v1 relay, please use the standalone relay daemon: https://github.com/libp2p/go-libp2p-relay-daemon (with RelayV1.Enabled: true)") } + // Swarm.ResourceMgr + enableResourceMgr := cfg.Swarm.ResourceMgr.Enabled.WithDefault(false) + /// ENV overrides Config (if present) + switch os.Getenv("IPFS_RCMGR") { + case "0", "false": + enableResourceMgr = false + case "1", "true": + enableResourceMgr = true + } + // Gather all the options opts := fx.Options( BaseLibP2P, // Services (resource management) - fx.Provide(libp2p.ResourceManager(cfg.Swarm.ResourceMgr)), + maybeProvide(libp2p.ResourceManager(cfg.Swarm.ResourceMgr), enableResourceMgr), fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index c4af75ae142..c6ab94ec489 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -26,66 +26,48 @@ func ResourceManager(cfg cfg.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network var manager network.ResourceManager var opts Libp2pOpts - // Config Swarm.ResourceMgr.Enabled decides if we run a real manager - enabled := cfg.Enabled.WithDefault(false) - - /// ENV overrides Config (if present) - // TODO: document IPFS_RCMGR and IPFS_DEBUG_RCMGR in docs/environment-variables.md - switch os.Getenv("IPFS_RCMGR") { - case "0", "false": - enabled = false - case "1", "true": - enabled = true + log.Debug("libp2p resource manager is enabled") + + // Try defaults from limit.json if provided + // (a convention to make libp2p team life easier) + // TODO: look in current dir and in IPFS_PATH + _, err := os.Stat(NetLimitDefaultFilename) + if !errors.Is(err, os.ErrNotExist) { + limitFile, err := os.Open(NetLimitDefaultFilename) + if err != nil { + return nil, opts, fmt.Errorf("error opening limit JSON file %s: %w", + NetLimitDefaultFilename, err) + } + defer limitFile.Close() //nolint:errcheck + limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitFile) + if err != nil { + return nil, opts, fmt.Errorf("error parsing limit file: %w", err) + } + + } else { + // Use defaults from go-libp2p + log.Debug("limit file %s not found, creating a default resource manager", NetLimitDefaultFilename) + limiter = rcmgr.NewDefaultLimiter() } - if enabled { - log.Debug("libp2p resource manager is enabled") - - // Try defaults from limit.json if provided - // (a convention to make libp2p team life easier) - // TODO: look in current dir and in IPFS_PATH - _, err := os.Stat(NetLimitDefaultFilename) - if !errors.Is(err, os.ErrNotExist) { - limitFile, err := os.Open(NetLimitDefaultFilename) - if err != nil { - return nil, opts, fmt.Errorf("error opening limit JSON file %s: %w", - NetLimitDefaultFilename, err) - } - defer limitFile.Close() //nolint:errcheck - limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitFile) - if err != nil { - return nil, opts, fmt.Errorf("error parsing limit file: %w", err) - } - - } else { - // Use defaults from go-libp2p - log.Debug("limit file %s not found, creating a default resource manager", NetLimitDefaultFilename) - limiter = rcmgr.NewDefaultLimiter() - } + libp2p.SetDefaultServiceLimits(limiter) - libp2p.SetDefaultServiceLimits(limiter) + var ropts []rcmgr.Option + if os.Getenv("IPFS_DEBUG_RCMGR") != "" { + ropts = append(ropts, rcmgr.WithTrace("rcmgr.json.gz")) + } - var ropts []rcmgr.Option - if os.Getenv("IPFS_DEBUG_RCMGR") != "" { - ropts = append(ropts, rcmgr.WithTrace("rcmgr.json.gz")) - } + manager, err = rcmgr.NewResourceManager(limiter, ropts...) + if err != nil { + return nil, opts, fmt.Errorf("error creating resource manager: %w", err) + } - manager, err = rcmgr.NewResourceManager(limiter, ropts...) + // Apply user-defined Swarm.ResourceMgr.Limits + for scope, userLimit := range cfg.Limits { + err := NetSetLimit(manager, scope, userLimit) if err != nil { - return nil, opts, fmt.Errorf("error creating resource manager: %w", err) + return nil, opts, fmt.Errorf("error while applying Swarm.ResourceMgr.Limits for scope %q: %w", scope, err) } - - // Apply user-defined Swarm.ResourceMgr.Limits - for scope, userLimit := range cfg.Limits { - err := NetSetLimit(manager, scope, userLimit) - if err != nil { - return nil, opts, fmt.Errorf("error while applying Swarm.ResourceMgr.Limits for scope %q: %w", scope, err) - } - } - - } else { - log.Debug("libp2p resource manager is disabled") - manager = network.NullResourceManager } opts.Opts = append(opts.Opts, libp2p.ResourceManager(manager)) From ed4eaa4434a4ec98dbc7b604771d57797045d1b3 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 4 Apr 2022 16:09:20 +0200 Subject: [PATCH 11/22] fix: use NullResourceManager when disabled This reverts commit b19f7c9eca4cee4187f8cba3389dc2c930258512. after clarification feedback from https://github.com/ipfs/go-ipfs/pull/8680#discussion_r841680182 --- core/node/groups.go | 13 +----- core/node/libp2p/rcmgr.go | 87 +++++++++++++++++++++-------------- docs/environment-variables.md | 16 +++++++ 3 files changed, 69 insertions(+), 47 deletions(-) diff --git a/core/node/groups.go b/core/node/groups.go index 992c9ab446a..48ee175a33c 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "os" "time" blockstore "github.com/ipfs/go-ipfs-blockstore" @@ -141,22 +140,12 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { "If you want to continue running a circuit v1 relay, please use the standalone relay daemon: https://github.com/libp2p/go-libp2p-relay-daemon (with RelayV1.Enabled: true)") } - // Swarm.ResourceMgr - enableResourceMgr := cfg.Swarm.ResourceMgr.Enabled.WithDefault(false) - /// ENV overrides Config (if present) - switch os.Getenv("IPFS_RCMGR") { - case "0", "false": - enableResourceMgr = false - case "1", "true": - enableResourceMgr = true - } - // Gather all the options opts := fx.Options( BaseLibP2P, // Services (resource management) - maybeProvide(libp2p.ResourceManager(cfg.Swarm.ResourceMgr), enableResourceMgr), + fx.Provide(libp2p.ResourceManager(cfg.Swarm.ResourceMgr)), fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index c6ab94ec489..17c7fac8c04 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -26,48 +26,65 @@ func ResourceManager(cfg cfg.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network var manager network.ResourceManager var opts Libp2pOpts - log.Debug("libp2p resource manager is enabled") - - // Try defaults from limit.json if provided - // (a convention to make libp2p team life easier) - // TODO: look in current dir and in IPFS_PATH - _, err := os.Stat(NetLimitDefaultFilename) - if !errors.Is(err, os.ErrNotExist) { - limitFile, err := os.Open(NetLimitDefaultFilename) - if err != nil { - return nil, opts, fmt.Errorf("error opening limit JSON file %s: %w", - NetLimitDefaultFilename, err) - } - defer limitFile.Close() //nolint:errcheck - limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitFile) - if err != nil { - return nil, opts, fmt.Errorf("error parsing limit file: %w", err) - } - - } else { - // Use defaults from go-libp2p - log.Debug("limit file %s not found, creating a default resource manager", NetLimitDefaultFilename) - limiter = rcmgr.NewDefaultLimiter() + // Config Swarm.ResourceMgr.Enabled decides if we run a real manager + enabled := cfg.Enabled.WithDefault(false) + + /// ENV overrides Config (if present) + switch os.Getenv("IPFS_RCMGR") { + case "0", "false": + enabled = false + case "1", "true": + enabled = true } - libp2p.SetDefaultServiceLimits(limiter) + if enabled { + log.Debug("libp2p resource manager is enabled") + + // Try defaults from limit.json if provided + // (a convention to make libp2p team life easier) + // TODO: look in current dir and in IPFS_PATH + _, err := os.Stat(NetLimitDefaultFilename) + if !errors.Is(err, os.ErrNotExist) { + limitFile, err := os.Open(NetLimitDefaultFilename) + if err != nil { + return nil, opts, fmt.Errorf("error opening limit JSON file %s: %w", + NetLimitDefaultFilename, err) + } + defer limitFile.Close() //nolint:errcheck + limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitFile) + if err != nil { + return nil, opts, fmt.Errorf("error parsing limit file: %w", err) + } + + } else { + // Use defaults from go-libp2p + log.Debug("limit file %s not found, creating a default resource manager", NetLimitDefaultFilename) + limiter = rcmgr.NewDefaultLimiter() + } - var ropts []rcmgr.Option - if os.Getenv("IPFS_DEBUG_RCMGR") != "" { - ropts = append(ropts, rcmgr.WithTrace("rcmgr.json.gz")) - } + libp2p.SetDefaultServiceLimits(limiter) - manager, err = rcmgr.NewResourceManager(limiter, ropts...) - if err != nil { - return nil, opts, fmt.Errorf("error creating resource manager: %w", err) - } + var ropts []rcmgr.Option + if os.Getenv("IPFS_DEBUG_RCMGR") != "" { + ropts = append(ropts, rcmgr.WithTrace("rcmgr.json.gz")) + } - // Apply user-defined Swarm.ResourceMgr.Limits - for scope, userLimit := range cfg.Limits { - err := NetSetLimit(manager, scope, userLimit) + manager, err = rcmgr.NewResourceManager(limiter, ropts...) if err != nil { - return nil, opts, fmt.Errorf("error while applying Swarm.ResourceMgr.Limits for scope %q: %w", scope, err) + return nil, opts, fmt.Errorf("error creating resource manager: %w", err) } + + // Apply user-defined Swarm.ResourceMgr.Limits + for scope, userLimit := range cfg.Limits { + err := NetSetLimit(manager, scope, userLimit) + if err != nil { + return nil, opts, fmt.Errorf("error while applying Swarm.ResourceMgr.Limits for scope %q: %w", scope, err) + } + } + + } else { + log.Debug("libp2p resource manager is disabled") + manager = network.NullResourceManager } opts.Opts = append(opts.Opts, libp2p.ResourceManager(manager)) diff --git a/docs/environment-variables.md b/docs/environment-variables.md index 174e283f9fc..14247b8df25 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -102,3 +102,19 @@ Deprecated: Use the `Swarm.Transports.Multiplexers` config field. Tells go-ipfs which multiplexers to use in which order. Default: "/yamux/1.0.0 /mplex/6.7.0" + +## `IPFS_RCMGR` + +Forces [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) +to be enabled (`1`) or disabled (`0`). +When set, overrides [`Swarm.ResourceMgr.Enabled`](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgrenabled) from the config. + +Default: use config (not set) + +## `IPFS_DEBUG_RCMGR` + +Enables tracing of [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) +and outputs it to `rcmgr.json.gz` + + +Default: disabled (not set) From 967249790be379c4885388bfc50a0c92a0dc9dbb Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 4 Apr 2022 16:26:43 +0200 Subject: [PATCH 12/22] style: rename IPFS_RCMGR to LIBP2P_RCMGR preexisting libp2p toggles use LIBP2P_ prefix --- core/node/libp2p/rcmgr.go | 4 ++-- docs/environment-variables.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 17c7fac8c04..3cb6cb0eba4 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -30,7 +30,7 @@ func ResourceManager(cfg cfg.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network enabled := cfg.Enabled.WithDefault(false) /// ENV overrides Config (if present) - switch os.Getenv("IPFS_RCMGR") { + switch os.Getenv("LIBP2P_RCMGR") { case "0", "false": enabled = false case "1", "true": @@ -65,7 +65,7 @@ func ResourceManager(cfg cfg.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network libp2p.SetDefaultServiceLimits(limiter) var ropts []rcmgr.Option - if os.Getenv("IPFS_DEBUG_RCMGR") != "" { + if os.Getenv("LIBP2P_DEBUG_RCMGR") != "" { ropts = append(ropts, rcmgr.WithTrace("rcmgr.json.gz")) } diff --git a/docs/environment-variables.md b/docs/environment-variables.md index 14247b8df25..3830638a656 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -103,7 +103,7 @@ Tells go-ipfs which multiplexers to use in which order. Default: "/yamux/1.0.0 /mplex/6.7.0" -## `IPFS_RCMGR` +## `LIBP2P_RCMGR` Forces [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) to be enabled (`1`) or disabled (`0`). @@ -111,7 +111,7 @@ When set, overrides [`Swarm.ResourceMgr.Enabled`](https://github.com/ipfs/go-ipf Default: use config (not set) -## `IPFS_DEBUG_RCMGR` +## `LIBP2P_DEBUG_RCMGR` Enables tracing of [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) and outputs it to `rcmgr.json.gz` From f8aeac43b109b2272c1f211559a4181281b10136 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 5 Apr 2022 15:43:07 +0200 Subject: [PATCH 13/22] test: Swarm.ResourceMgr --- core/commands/swarm.go | 4 +- core/node/libp2p/rcmgr.go | 14 ++++--- test/sharness/t0139-swarm-rcmgr.sh | 66 ++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 8 deletions(-) create mode 100755 test/sharness/t0139-swarm-rcmgr.sh diff --git a/core/commands/swarm.go b/core/commands/swarm.go index a213db6f74f..fdd61308fa9 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -335,7 +335,7 @@ The output of this command is JSON. } if node.ResourceManager == nil { - return fmt.Errorf("no resource manager available, make sure the daemon is running") + return libp2p.NoResourceMgrError } if len(req.Arguments) != 1 { @@ -394,7 +394,7 @@ For permanent limits set Swarm.ResourceMgr.Limits in the $IPFS_PATH/config file. } if node.ResourceManager == nil { - return fmt.Errorf("no resource manager available: make sure the daemon is running with Swarm.ResourceMgr.Enabled in the config") + return libp2p.NoResourceMgrError } scope := req.Arguments[0] diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 3cb6cb0eba4..0a0272d7285 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -20,6 +20,8 @@ import ( const NetLimitDefaultFilename = "limit.json" +var NoResourceMgrError = fmt.Errorf("missing ResourceMgr: make sure the daemon is running with Swarm.ResourceMgr.Enabled") + func ResourceManager(cfg cfg.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network.ResourceManager, Libp2pOpts, error) { return func(lc fx.Lifecycle, repo repo.Repo) (network.ResourceManager, Libp2pOpts, error) { var limiter *rcmgr.BasicLimiter @@ -112,8 +114,8 @@ func NetStat(mgr network.ResourceManager, scope string) (NetStatOut, error) { switch { case scope == "all": rapi, ok := mgr.(rcmgr.ResourceManagerState) - if !ok { - return result, fmt.Errorf("resource manager does not support ResourceManagerState API") + if !ok { // NullResourceManager + return result, NoResourceMgrError } stat := rapi.Stat() @@ -199,8 +201,8 @@ func NetLimit(mgr network.ResourceManager, scope string) (config.ResourceMgrScop var result config.ResourceMgrScopeConfig getLimit := func(s network.ResourceScope) error { limiter, ok := s.(rcmgr.ResourceScopeLimiter) - if !ok { - return fmt.Errorf("resource scope doesn't implement ResourceScopeLimiter interface") + if !ok { // NullResourceManager + return NoResourceMgrError } limit := limiter.Limit() @@ -282,8 +284,8 @@ func NetLimit(mgr network.ResourceManager, scope string) (config.ResourceMgrScop func NetSetLimit(mgr network.ResourceManager, scope string, limit config.ResourceMgrScopeConfig) error { setLimit := func(s network.ResourceScope) error { limiter, ok := s.(rcmgr.ResourceScopeLimiter) - if !ok { - return fmt.Errorf("resource scope doesn't implement ResourceScopeLimiter interface") + if !ok { // NullResourceManager + return NoResourceMgrError } var newLimit rcmgr.Limit diff --git a/test/sharness/t0139-swarm-rcmgr.sh b/test/sharness/t0139-swarm-rcmgr.sh new file mode 100755 index 00000000000..39bbf1d5204 --- /dev/null +++ b/test/sharness/t0139-swarm-rcmgr.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# +test_description="Test ipfs swarm ResourceMgr config and commands" + +. lib/test-lib.sh + +test_init_ipfs + +# swarm limit|stats should fail in offline mode + +test_expect_success 'disconnected: swarm limit requires running daemon' ' + test_expect_code 1 ipfs swarm limit system 2> actual && + test_should_contain "missing ResourceMgr" actual +' +test_expect_success 'disconnected: swarm stats requires running daemon' ' + test_expect_code 1 ipfs swarm stats all 2> actual && + test_should_contain "missing ResourceMgr" actual +' + +# swarm limit|stats should fail in online mode by default +# because Resource Manager is opt-in for now +test_launch_ipfs_daemon + +test_expect_success 'ResourceMgr disabled by default: swarm limit requires Swarm.ResourceMgr.Enabled' ' + test_expect_code 1 ipfs swarm limit system 2> actual && + test_should_contain "missing ResourceMgr" actual +' +test_expect_success 'ResourceMgr disabled by default: swarm stats requires Swarm.ResourceMgr.Enabled' ' + test_expect_code 1 ipfs swarm stats all 2> actual && + test_should_contain "missing ResourceMgr" actual +' + +# swarm limit|stat should work when Swarm.ResourceMgr.Enabled +test_kill_ipfs_daemon +test_expect_success "test_config_set succeeds" " + ipfs config --json Swarm.ResourceMgr.Enabled true +" +test_launch_ipfs_daemon + +# every scope has the same fields, so we only inspect System +test_expect_success 'ResourceMgr enabled: swarm limit' ' + ipfs swarm limit system --enc=json | tee json && + jq -e .Conns < json && + jq -e .ConnsInbound < json && + jq -e .ConnsOutbound < json && + jq -e .FD < json && + jq -e .Memory < json && + jq -e .Streams < json && + jq -e .StreamsInbound < json && + jq -e .StreamsOutbound < json +' + +# every scope has the same fields, so we only inspect System +test_expect_success 'ResourceMgr enabled: swarm stats' ' + ipfs swarm stats all --enc=json | tee json && + jq -e .System.Memory < json && + jq -e .System.NumConnsInbound < json && + jq -e .System.NumConnsOutbound < json && + jq -e .System.NumFD < json && + jq -e .System.NumStreamsInbound < json && + jq -e .System.NumStreamsOutbound < json && + jq -e .Transient.Memory < json +' + +test_kill_ipfs_daemon +test_done From 345dcb1148034796dc44e35000b3ed2eb37e76bc Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 5 Apr 2022 16:11:09 +0200 Subject: [PATCH 14/22] fix: location of opt-in limit.json and rcmgr.json.gz Places these files inside of IPFS_PATH --- core/node/libp2p/rcmgr.go | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 0a0272d7285..5e85df6c712 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -5,9 +5,9 @@ import ( "errors" "fmt" "os" + "path/filepath" "strings" - cfg "github.com/ipfs/go-ipfs/config" config "github.com/ipfs/go-ipfs/config" "github.com/ipfs/go-ipfs/repo" "github.com/libp2p/go-libp2p" @@ -19,10 +19,11 @@ import ( ) const NetLimitDefaultFilename = "limit.json" +const NetLimitTraceFilename = "rcmgr.json.gz" var NoResourceMgrError = fmt.Errorf("missing ResourceMgr: make sure the daemon is running with Swarm.ResourceMgr.Enabled") -func ResourceManager(cfg cfg.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network.ResourceManager, Libp2pOpts, error) { +func ResourceManager(cfg config.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network.ResourceManager, Libp2pOpts, error) { return func(lc fx.Lifecycle, repo repo.Repo) (network.ResourceManager, Libp2pOpts, error) { var limiter *rcmgr.BasicLimiter var manager network.ResourceManager @@ -42,15 +43,19 @@ func ResourceManager(cfg cfg.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network if enabled { log.Debug("libp2p resource manager is enabled") + repoPath, err := config.PathRoot() + if err != nil { + return nil, opts, fmt.Errorf("error opening IPFS_PATH: %w", err) + } + // Try defaults from limit.json if provided // (a convention to make libp2p team life easier) - // TODO: look in current dir and in IPFS_PATH - _, err := os.Stat(NetLimitDefaultFilename) + limitFilePath := filepath.Join(repoPath, NetLimitDefaultFilename) + _, err = os.Stat(limitFilePath) if !errors.Is(err, os.ErrNotExist) { - limitFile, err := os.Open(NetLimitDefaultFilename) + limitFile, err := os.Open(limitFilePath) if err != nil { - return nil, opts, fmt.Errorf("error opening limit JSON file %s: %w", - NetLimitDefaultFilename, err) + return nil, opts, fmt.Errorf("error opening limit JSON file %q: %w", limitFilePath, err) } defer limitFile.Close() //nolint:errcheck limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitFile) @@ -68,7 +73,8 @@ func ResourceManager(cfg cfg.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network var ropts []rcmgr.Option if os.Getenv("LIBP2P_DEBUG_RCMGR") != "" { - ropts = append(ropts, rcmgr.WithTrace("rcmgr.json.gz")) + traceFilePath := filepath.Join(repoPath, NetLimitTraceFilename) + ropts = append(ropts, rcmgr.WithTrace(traceFilePath)) } manager, err = rcmgr.NewResourceManager(limiter, ropts...) From bfc52ab0a73e9b8bf2b40c5f1cf87234ba197615 Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Tue, 5 Apr 2022 13:17:21 -0300 Subject: [PATCH 15/22] Update docs/config.md --- docs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index 8a17dc9880d..8b6d3aabe46 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1638,7 +1638,7 @@ and track recource usage over time. #### `Swarm.ResourceMgr.Enabled` -**EXPERIMENTAL**: this feature is is disabled by default, use with caution. +**EXPERIMENTAL**: this feature is disabled by default, use with caution. Enables the libp2p Network Resource Manager and auguments the default limits using user-defined ones in `Swarm.ResourceMgr.Limits` (if present). From 41db58d191324442f3e0b47b919aa87a33ea04ef Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 5 Apr 2022 23:51:56 +0100 Subject: [PATCH 16/22] feat: expose rcmgr metrics when enabled (#8785) * add metrics for the resource manager * export protocol and service name in Prometheus metrics * fix: expose rcmgr metrics only when enabled Co-authored-by: Marcin Rataj --- core/node/groups.go | 1 - core/node/libp2p/rcmgr.go | 234 +++++++++++++++++++++++++++++++++++++- go.mod | 6 +- 3 files changed, 236 insertions(+), 5 deletions(-) diff --git a/core/node/groups.go b/core/node/groups.go index 48ee175a33c..a713f36ca37 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -146,7 +146,6 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { // Services (resource management) fx.Provide(libp2p.ResourceManager(cfg.Swarm.ResourceMgr)), - fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), fx.Provide(libp2p.SmuxTransport(cfg.Swarm.Transports)), diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 5e85df6c712..747322b8f95 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -6,15 +6,19 @@ import ( "fmt" "os" "path/filepath" + "strconv" "strings" config "github.com/ipfs/go-ipfs/config" "github.com/ipfs/go-ipfs/repo" + "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/protocol" rcmgr "github.com/libp2p/go-libp2p-resource-manager" + + "github.com/prometheus/client_golang/prometheus" "go.uber.org/fx" ) @@ -71,7 +75,8 @@ func ResourceManager(cfg config.ResourceMgr) func(fx.Lifecycle, repo.Repo) (netw libp2p.SetDefaultServiceLimits(limiter) - var ropts []rcmgr.Option + ropts := []rcmgr.Option{rcmgr.WithMetrics(createRcmgrMetrics())} + if os.Getenv("LIBP2P_DEBUG_RCMGR") != "" { traceFilePath := filepath.Join(repoPath, NetLimitTraceFilename) ropts = append(ropts, rcmgr.WithTrace(traceFilePath)) @@ -373,3 +378,230 @@ func NetSetLimit(mgr network.ResourceManager, scope string, limit config.Resourc return fmt.Errorf("invalid scope %q", scope) } } + +func createRcmgrMetrics() rcmgr.MetricsReporter { + const ( + direction = "direction" + usesFD = "usesFD" + protocol = "protocol" + service = "service" + ) + + connAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_conns_allowed_total", + Help: "allowed connections", + }, + []string{direction, usesFD}, + ) + prometheus.MustRegister(connAllowed) + + connBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_conns_blocked_total", + Help: "blocked connections", + }, + []string{direction, usesFD}, + ) + prometheus.MustRegister(connBlocked) + + streamAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_streams_allowed_total", + Help: "allowed streams", + }, + []string{direction}, + ) + prometheus.MustRegister(streamAllowed) + + streamBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_streams_blocked_total", + Help: "blocked streams", + }, + []string{direction}, + ) + prometheus.MustRegister(streamBlocked) + + peerAllowed := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_peers_allowed_total", + Help: "allowed peers", + }) + prometheus.MustRegister(peerAllowed) + + peerBlocked := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_peer_blocked_total", + Help: "blocked peers", + }) + prometheus.MustRegister(peerBlocked) + + protocolAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_protocols_allowed_total", + Help: "allowed streams attached to a protocol", + }, + []string{protocol}, + ) + prometheus.MustRegister(protocolAllowed) + + protocolBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_protocols_blocked_total", + Help: "blocked streams attached to a protocol", + }, + []string{protocol}, + ) + prometheus.MustRegister(protocolBlocked) + + protocolPeerBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_protocols_for_peer_blocked_total", + Help: "blocked streams attached to a protocol for a specific peer", + }, + []string{protocol}, + ) + prometheus.MustRegister(protocolPeerBlocked) + + serviceAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_services_allowed_total", + Help: "allowed streams attached to a service", + }, + []string{service}, + ) + prometheus.MustRegister(serviceAllowed) + + serviceBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_services_blocked_total", + Help: "blocked streams attached to a service", + }, + []string{service}, + ) + prometheus.MustRegister(serviceBlocked) + + servicePeerBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_service_for_peer_blocked_total", + Help: "blocked streams attached to a service for a specific peer", + }, + []string{service}, + ) + prometheus.MustRegister(servicePeerBlocked) + + memoryAllowed := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_memory_allocations_allowed_total", + Help: "allowed memory allocations", + }) + prometheus.MustRegister(memoryAllowed) + + memoryBlocked := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_memory_allocations_blocked_total", + Help: "blocked memory allocations", + }) + prometheus.MustRegister(memoryBlocked) + + return rcmgrMetrics{ + connAllowed, + connBlocked, + streamAllowed, + streamBlocked, + peerAllowed, + peerBlocked, + protocolAllowed, + protocolBlocked, + protocolPeerBlocked, + serviceAllowed, + serviceBlocked, + servicePeerBlocked, + memoryAllowed, + memoryBlocked, + } +} + +// Failsafe to ensure interface from go-libp2p-resource-manager is implemented +var _ rcmgr.MetricsReporter = rcmgrMetrics{} + +type rcmgrMetrics struct { + connAllowed *prometheus.CounterVec + connBlocked *prometheus.CounterVec + streamAllowed *prometheus.CounterVec + streamBlocked *prometheus.CounterVec + peerAllowed prometheus.Counter + peerBlocked prometheus.Counter + protocolAllowed *prometheus.CounterVec + protocolBlocked *prometheus.CounterVec + protocolPeerBlocked *prometheus.CounterVec + serviceAllowed *prometheus.CounterVec + serviceBlocked *prometheus.CounterVec + servicePeerBlocked *prometheus.CounterVec + memoryAllowed prometheus.Counter + memoryBlocked prometheus.Counter +} + +func getDirection(d network.Direction) string { + switch d { + default: + return "" + case network.DirInbound: + return "inbound" + case network.DirOutbound: + return "outbound" + } +} + +func (r rcmgrMetrics) AllowConn(dir network.Direction, usefd bool) { + r.connAllowed.WithLabelValues(getDirection(dir), strconv.FormatBool(usefd)).Inc() +} + +func (r rcmgrMetrics) BlockConn(dir network.Direction, usefd bool) { + r.connBlocked.WithLabelValues(getDirection(dir), strconv.FormatBool(usefd)).Inc() +} + +func (r rcmgrMetrics) AllowStream(_ peer.ID, dir network.Direction) { + r.streamAllowed.WithLabelValues(getDirection(dir)).Inc() +} + +func (r rcmgrMetrics) BlockStream(_ peer.ID, dir network.Direction) { + r.streamBlocked.WithLabelValues(getDirection(dir)).Inc() +} + +func (r rcmgrMetrics) AllowPeer(_ peer.ID) { + r.peerAllowed.Inc() +} + +func (r rcmgrMetrics) BlockPeer(_ peer.ID) { + r.peerBlocked.Inc() +} + +func (r rcmgrMetrics) AllowProtocol(proto protocol.ID) { + r.protocolAllowed.WithLabelValues(string(proto)).Inc() +} + +func (r rcmgrMetrics) BlockProtocol(proto protocol.ID) { + r.protocolBlocked.WithLabelValues(string(proto)).Inc() +} + +func (r rcmgrMetrics) BlockProtocolPeer(proto protocol.ID, _ peer.ID) { + r.protocolPeerBlocked.WithLabelValues(string(proto)).Inc() +} + +func (r rcmgrMetrics) AllowService(svc string) { + r.serviceAllowed.WithLabelValues(svc).Inc() +} + +func (r rcmgrMetrics) BlockService(svc string) { + r.serviceBlocked.WithLabelValues(svc).Inc() +} + +func (r rcmgrMetrics) BlockServicePeer(svc string, _ peer.ID) { + r.servicePeerBlocked.WithLabelValues(svc).Inc() +} + +func (r rcmgrMetrics) AllowMemory(_ int) { + r.memoryAllowed.Inc() +} + +func (r rcmgrMetrics) BlockMemory(_ int) { + r.memoryBlocked.Inc() +} diff --git a/go.mod b/go.mod index 33c8a5e4a11..325b7955e5c 100644 --- a/go.mod +++ b/go.mod @@ -105,9 +105,6 @@ require ( github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 go.opencensus.io v0.23.0 - go.uber.org/dig v1.14.0 - go.uber.org/fx v1.16.0 - go.uber.org/zap v1.21.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0 go.opentelemetry.io/otel v1.2.0 go.opentelemetry.io/otel/exporters/jaeger v1.2.0 @@ -116,6 +113,9 @@ require ( go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.2.0 go.opentelemetry.io/otel/sdk v1.2.0 go.opentelemetry.io/otel/trace v1.2.0 + go.uber.org/dig v1.14.0 + go.uber.org/fx v1.16.0 + go.uber.org/zap v1.21.0 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20211025112917-711f33c9992c From ee0f58dc93b02f0885fea6a198f4b19f672fbf4e Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 6 Apr 2022 19:10:43 +0200 Subject: [PATCH 17/22] refactor: rcmgr_metrics.go --- core/node/libp2p/rcmgr.go | 229 ---------------------------- core/node/libp2p/rcmgr_metrics.go | 239 ++++++++++++++++++++++++++++++ 2 files changed, 239 insertions(+), 229 deletions(-) create mode 100644 core/node/libp2p/rcmgr_metrics.go diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 747322b8f95..3154a2bde66 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -6,7 +6,6 @@ import ( "fmt" "os" "path/filepath" - "strconv" "strings" config "github.com/ipfs/go-ipfs/config" @@ -18,7 +17,6 @@ import ( "github.com/libp2p/go-libp2p-core/protocol" rcmgr "github.com/libp2p/go-libp2p-resource-manager" - "github.com/prometheus/client_golang/prometheus" "go.uber.org/fx" ) @@ -378,230 +376,3 @@ func NetSetLimit(mgr network.ResourceManager, scope string, limit config.Resourc return fmt.Errorf("invalid scope %q", scope) } } - -func createRcmgrMetrics() rcmgr.MetricsReporter { - const ( - direction = "direction" - usesFD = "usesFD" - protocol = "protocol" - service = "service" - ) - - connAllowed := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "libp2p_rcmgr_conns_allowed_total", - Help: "allowed connections", - }, - []string{direction, usesFD}, - ) - prometheus.MustRegister(connAllowed) - - connBlocked := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "libp2p_rcmgr_conns_blocked_total", - Help: "blocked connections", - }, - []string{direction, usesFD}, - ) - prometheus.MustRegister(connBlocked) - - streamAllowed := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "libp2p_rcmgr_streams_allowed_total", - Help: "allowed streams", - }, - []string{direction}, - ) - prometheus.MustRegister(streamAllowed) - - streamBlocked := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "libp2p_rcmgr_streams_blocked_total", - Help: "blocked streams", - }, - []string{direction}, - ) - prometheus.MustRegister(streamBlocked) - - peerAllowed := prometheus.NewCounter(prometheus.CounterOpts{ - Name: "libp2p_rcmgr_peers_allowed_total", - Help: "allowed peers", - }) - prometheus.MustRegister(peerAllowed) - - peerBlocked := prometheus.NewCounter(prometheus.CounterOpts{ - Name: "libp2p_rcmgr_peer_blocked_total", - Help: "blocked peers", - }) - prometheus.MustRegister(peerBlocked) - - protocolAllowed := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "libp2p_rcmgr_protocols_allowed_total", - Help: "allowed streams attached to a protocol", - }, - []string{protocol}, - ) - prometheus.MustRegister(protocolAllowed) - - protocolBlocked := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "libp2p_rcmgr_protocols_blocked_total", - Help: "blocked streams attached to a protocol", - }, - []string{protocol}, - ) - prometheus.MustRegister(protocolBlocked) - - protocolPeerBlocked := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "libp2p_rcmgr_protocols_for_peer_blocked_total", - Help: "blocked streams attached to a protocol for a specific peer", - }, - []string{protocol}, - ) - prometheus.MustRegister(protocolPeerBlocked) - - serviceAllowed := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "libp2p_rcmgr_services_allowed_total", - Help: "allowed streams attached to a service", - }, - []string{service}, - ) - prometheus.MustRegister(serviceAllowed) - - serviceBlocked := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "libp2p_rcmgr_services_blocked_total", - Help: "blocked streams attached to a service", - }, - []string{service}, - ) - prometheus.MustRegister(serviceBlocked) - - servicePeerBlocked := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "libp2p_rcmgr_service_for_peer_blocked_total", - Help: "blocked streams attached to a service for a specific peer", - }, - []string{service}, - ) - prometheus.MustRegister(servicePeerBlocked) - - memoryAllowed := prometheus.NewCounter(prometheus.CounterOpts{ - Name: "libp2p_rcmgr_memory_allocations_allowed_total", - Help: "allowed memory allocations", - }) - prometheus.MustRegister(memoryAllowed) - - memoryBlocked := prometheus.NewCounter(prometheus.CounterOpts{ - Name: "libp2p_rcmgr_memory_allocations_blocked_total", - Help: "blocked memory allocations", - }) - prometheus.MustRegister(memoryBlocked) - - return rcmgrMetrics{ - connAllowed, - connBlocked, - streamAllowed, - streamBlocked, - peerAllowed, - peerBlocked, - protocolAllowed, - protocolBlocked, - protocolPeerBlocked, - serviceAllowed, - serviceBlocked, - servicePeerBlocked, - memoryAllowed, - memoryBlocked, - } -} - -// Failsafe to ensure interface from go-libp2p-resource-manager is implemented -var _ rcmgr.MetricsReporter = rcmgrMetrics{} - -type rcmgrMetrics struct { - connAllowed *prometheus.CounterVec - connBlocked *prometheus.CounterVec - streamAllowed *prometheus.CounterVec - streamBlocked *prometheus.CounterVec - peerAllowed prometheus.Counter - peerBlocked prometheus.Counter - protocolAllowed *prometheus.CounterVec - protocolBlocked *prometheus.CounterVec - protocolPeerBlocked *prometheus.CounterVec - serviceAllowed *prometheus.CounterVec - serviceBlocked *prometheus.CounterVec - servicePeerBlocked *prometheus.CounterVec - memoryAllowed prometheus.Counter - memoryBlocked prometheus.Counter -} - -func getDirection(d network.Direction) string { - switch d { - default: - return "" - case network.DirInbound: - return "inbound" - case network.DirOutbound: - return "outbound" - } -} - -func (r rcmgrMetrics) AllowConn(dir network.Direction, usefd bool) { - r.connAllowed.WithLabelValues(getDirection(dir), strconv.FormatBool(usefd)).Inc() -} - -func (r rcmgrMetrics) BlockConn(dir network.Direction, usefd bool) { - r.connBlocked.WithLabelValues(getDirection(dir), strconv.FormatBool(usefd)).Inc() -} - -func (r rcmgrMetrics) AllowStream(_ peer.ID, dir network.Direction) { - r.streamAllowed.WithLabelValues(getDirection(dir)).Inc() -} - -func (r rcmgrMetrics) BlockStream(_ peer.ID, dir network.Direction) { - r.streamBlocked.WithLabelValues(getDirection(dir)).Inc() -} - -func (r rcmgrMetrics) AllowPeer(_ peer.ID) { - r.peerAllowed.Inc() -} - -func (r rcmgrMetrics) BlockPeer(_ peer.ID) { - r.peerBlocked.Inc() -} - -func (r rcmgrMetrics) AllowProtocol(proto protocol.ID) { - r.protocolAllowed.WithLabelValues(string(proto)).Inc() -} - -func (r rcmgrMetrics) BlockProtocol(proto protocol.ID) { - r.protocolBlocked.WithLabelValues(string(proto)).Inc() -} - -func (r rcmgrMetrics) BlockProtocolPeer(proto protocol.ID, _ peer.ID) { - r.protocolPeerBlocked.WithLabelValues(string(proto)).Inc() -} - -func (r rcmgrMetrics) AllowService(svc string) { - r.serviceAllowed.WithLabelValues(svc).Inc() -} - -func (r rcmgrMetrics) BlockService(svc string) { - r.serviceBlocked.WithLabelValues(svc).Inc() -} - -func (r rcmgrMetrics) BlockServicePeer(svc string, _ peer.ID) { - r.servicePeerBlocked.WithLabelValues(svc).Inc() -} - -func (r rcmgrMetrics) AllowMemory(_ int) { - r.memoryAllowed.Inc() -} - -func (r rcmgrMetrics) BlockMemory(_ int) { - r.memoryBlocked.Inc() -} diff --git a/core/node/libp2p/rcmgr_metrics.go b/core/node/libp2p/rcmgr_metrics.go new file mode 100644 index 00000000000..56ccfa9d62d --- /dev/null +++ b/core/node/libp2p/rcmgr_metrics.go @@ -0,0 +1,239 @@ +package libp2p + +import ( + "strconv" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" + rcmgr "github.com/libp2p/go-libp2p-resource-manager" + + "github.com/prometheus/client_golang/prometheus" +) + +func createRcmgrMetrics() rcmgr.MetricsReporter { + const ( + direction = "direction" + usesFD = "usesFD" + protocol = "protocol" + service = "service" + ) + + connAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_conns_allowed_total", + Help: "allowed connections", + }, + []string{direction, usesFD}, + ) + prometheus.MustRegister(connAllowed) + + connBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_conns_blocked_total", + Help: "blocked connections", + }, + []string{direction, usesFD}, + ) + prometheus.MustRegister(connBlocked) + + streamAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_streams_allowed_total", + Help: "allowed streams", + }, + []string{direction}, + ) + prometheus.MustRegister(streamAllowed) + + streamBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_streams_blocked_total", + Help: "blocked streams", + }, + []string{direction}, + ) + prometheus.MustRegister(streamBlocked) + + peerAllowed := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_peers_allowed_total", + Help: "allowed peers", + }) + prometheus.MustRegister(peerAllowed) + + peerBlocked := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_peer_blocked_total", + Help: "blocked peers", + }) + prometheus.MustRegister(peerBlocked) + + protocolAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_protocols_allowed_total", + Help: "allowed streams attached to a protocol", + }, + []string{protocol}, + ) + prometheus.MustRegister(protocolAllowed) + + protocolBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_protocols_blocked_total", + Help: "blocked streams attached to a protocol", + }, + []string{protocol}, + ) + prometheus.MustRegister(protocolBlocked) + + protocolPeerBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_protocols_for_peer_blocked_total", + Help: "blocked streams attached to a protocol for a specific peer", + }, + []string{protocol}, + ) + prometheus.MustRegister(protocolPeerBlocked) + + serviceAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_services_allowed_total", + Help: "allowed streams attached to a service", + }, + []string{service}, + ) + prometheus.MustRegister(serviceAllowed) + + serviceBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_services_blocked_total", + Help: "blocked streams attached to a service", + }, + []string{service}, + ) + prometheus.MustRegister(serviceBlocked) + + servicePeerBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_service_for_peer_blocked_total", + Help: "blocked streams attached to a service for a specific peer", + }, + []string{service}, + ) + prometheus.MustRegister(servicePeerBlocked) + + memoryAllowed := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_memory_allocations_allowed_total", + Help: "allowed memory allocations", + }) + prometheus.MustRegister(memoryAllowed) + + memoryBlocked := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_memory_allocations_blocked_total", + Help: "blocked memory allocations", + }) + prometheus.MustRegister(memoryBlocked) + + return rcmgrMetrics{ + connAllowed, + connBlocked, + streamAllowed, + streamBlocked, + peerAllowed, + peerBlocked, + protocolAllowed, + protocolBlocked, + protocolPeerBlocked, + serviceAllowed, + serviceBlocked, + servicePeerBlocked, + memoryAllowed, + memoryBlocked, + } +} + +// Failsafe to ensure interface from go-libp2p-resource-manager is implemented +var _ rcmgr.MetricsReporter = rcmgrMetrics{} + +type rcmgrMetrics struct { + connAllowed *prometheus.CounterVec + connBlocked *prometheus.CounterVec + streamAllowed *prometheus.CounterVec + streamBlocked *prometheus.CounterVec + peerAllowed prometheus.Counter + peerBlocked prometheus.Counter + protocolAllowed *prometheus.CounterVec + protocolBlocked *prometheus.CounterVec + protocolPeerBlocked *prometheus.CounterVec + serviceAllowed *prometheus.CounterVec + serviceBlocked *prometheus.CounterVec + servicePeerBlocked *prometheus.CounterVec + memoryAllowed prometheus.Counter + memoryBlocked prometheus.Counter +} + +func getDirection(d network.Direction) string { + switch d { + default: + return "" + case network.DirInbound: + return "inbound" + case network.DirOutbound: + return "outbound" + } +} + +func (r rcmgrMetrics) AllowConn(dir network.Direction, usefd bool) { + r.connAllowed.WithLabelValues(getDirection(dir), strconv.FormatBool(usefd)).Inc() +} + +func (r rcmgrMetrics) BlockConn(dir network.Direction, usefd bool) { + r.connBlocked.WithLabelValues(getDirection(dir), strconv.FormatBool(usefd)).Inc() +} + +func (r rcmgrMetrics) AllowStream(_ peer.ID, dir network.Direction) { + r.streamAllowed.WithLabelValues(getDirection(dir)).Inc() +} + +func (r rcmgrMetrics) BlockStream(_ peer.ID, dir network.Direction) { + r.streamBlocked.WithLabelValues(getDirection(dir)).Inc() +} + +func (r rcmgrMetrics) AllowPeer(_ peer.ID) { + r.peerAllowed.Inc() +} + +func (r rcmgrMetrics) BlockPeer(_ peer.ID) { + r.peerBlocked.Inc() +} + +func (r rcmgrMetrics) AllowProtocol(proto protocol.ID) { + r.protocolAllowed.WithLabelValues(string(proto)).Inc() +} + +func (r rcmgrMetrics) BlockProtocol(proto protocol.ID) { + r.protocolBlocked.WithLabelValues(string(proto)).Inc() +} + +func (r rcmgrMetrics) BlockProtocolPeer(proto protocol.ID, _ peer.ID) { + r.protocolPeerBlocked.WithLabelValues(string(proto)).Inc() +} + +func (r rcmgrMetrics) AllowService(svc string) { + r.serviceAllowed.WithLabelValues(svc).Inc() +} + +func (r rcmgrMetrics) BlockService(svc string) { + r.serviceBlocked.WithLabelValues(svc).Inc() +} + +func (r rcmgrMetrics) BlockServicePeer(svc string, _ peer.ID) { + r.servicePeerBlocked.WithLabelValues(svc).Inc() +} + +func (r rcmgrMetrics) AllowMemory(_ int) { + r.memoryAllowed.Inc() +} + +func (r rcmgrMetrics) BlockMemory(_ int) { + r.memoryBlocked.Inc() +} From 55eeab07628b144a518fb25b8041703c2ae18caf Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 6 Apr 2022 19:31:33 +0200 Subject: [PATCH 18/22] refactor: rcmgr_defaults.go This file defines implicit limit defaults used when Swarm.ResourceMgr.Enabled We keep vendored copy to ensure go-ipfs is not impacted when go-libp2p decides to change defaults in any of the future releases. --- core/node/libp2p/rcmgr.go | 6 +- core/node/libp2p/rcmgr_defaults.go | 269 +++++++++++++++++++++++++++++ 2 files changed, 272 insertions(+), 3 deletions(-) create mode 100644 core/node/libp2p/rcmgr_defaults.go diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 3154a2bde66..3b9d8b70dc2 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -66,12 +66,12 @@ func ResourceManager(cfg config.ResourceMgr) func(fx.Lifecycle, repo.Repo) (netw } } else { - // Use defaults from go-libp2p + // Use defaults from rcmgr_defaults.go log.Debug("limit file %s not found, creating a default resource manager", NetLimitDefaultFilename) - limiter = rcmgr.NewDefaultLimiter() + limiter = newDefaultLimiter() // see rcmgr_defaults.go } - libp2p.SetDefaultServiceLimits(limiter) + setDefaultServiceLimits(limiter) // see rcmgr_defaults.go ropts := []rcmgr.Option{rcmgr.WithMetrics(createRcmgrMetrics())} diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go new file mode 100644 index 00000000000..b1942ffa662 --- /dev/null +++ b/core/node/libp2p/rcmgr_defaults.go @@ -0,0 +1,269 @@ +package libp2p + +import ( + "github.com/libp2p/go-libp2p-core/protocol" + rcmgr "github.com/libp2p/go-libp2p-resource-manager" + "github.com/libp2p/go-libp2p/p2p/host/autonat" + relayv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay" + circuit "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" + relayv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay" + "github.com/libp2p/go-libp2p/p2p/protocol/holepunch" + "github.com/libp2p/go-libp2p/p2p/protocol/identify" + "github.com/libp2p/go-libp2p/p2p/protocol/ping" +) + +// This file defines implicit limit defaults used when Swarm.ResourceMgr.Enabled +// We keep vendored copy to ensure go-ipfs is not impacted when go-libp2p decides +// to change defaults in any of the future releases. + +// defaultLimits are the limits used by the default rcmgr limiter constructors. +// This is a vendored copy of +// https://github.com/libp2p/go-libp2p-resource-manager/blob/v0.1.5/limit_defaults.go#L49 +var defaultLimits = rcmgr.DefaultLimitConfig{ + SystemBaseLimit: rcmgr.BaseLimit{ + StreamsInbound: 4096, + StreamsOutbound: 16384, + Streams: 16384, + ConnsInbound: 256, + ConnsOutbound: 1024, + Conns: 1024, + FD: 512, + }, + + SystemMemory: rcmgr.MemoryLimit{ + MemoryFraction: 0.125, + MinMemory: 128 << 20, + MaxMemory: 1 << 30, + }, + + TransientBaseLimit: rcmgr.BaseLimit{ + StreamsInbound: 128, + StreamsOutbound: 512, + Streams: 512, + ConnsInbound: 32, + ConnsOutbound: 128, + Conns: 128, + FD: 128, + }, + + TransientMemory: rcmgr.MemoryLimit{ + MemoryFraction: 1, + MinMemory: 64 << 20, + MaxMemory: 64 << 20, + }, + + ServiceBaseLimit: rcmgr.BaseLimit{ + StreamsInbound: 2048, + StreamsOutbound: 8192, + Streams: 8192, + }, + + ServiceMemory: rcmgr.MemoryLimit{ + MemoryFraction: 0.125 / 4, + MinMemory: 64 << 20, + MaxMemory: 256 << 20, + }, + + ServicePeerBaseLimit: rcmgr.BaseLimit{ + StreamsInbound: 256, + StreamsOutbound: 512, + Streams: 512, + }, + + ServicePeerMemory: rcmgr.MemoryLimit{ + MemoryFraction: 0.125 / 16, + MinMemory: 16 << 20, + MaxMemory: 64 << 20, + }, + + ProtocolBaseLimit: rcmgr.BaseLimit{ + StreamsInbound: 1024, + StreamsOutbound: 4096, + Streams: 4096, + }, + + ProtocolMemory: rcmgr.MemoryLimit{ + MemoryFraction: 0.125 / 8, + MinMemory: 64 << 20, + MaxMemory: 128 << 20, + }, + + ProtocolPeerBaseLimit: rcmgr.BaseLimit{ + StreamsInbound: 128, + StreamsOutbound: 256, + Streams: 512, + }, + + ProtocolPeerMemory: rcmgr.MemoryLimit{ + MemoryFraction: 0.125 / 16, + MinMemory: 16 << 20, + MaxMemory: 64 << 20, + }, + + PeerBaseLimit: rcmgr.BaseLimit{ + StreamsInbound: 512, + StreamsOutbound: 1024, + Streams: 1024, + ConnsInbound: 8, + ConnsOutbound: 16, + Conns: 16, + FD: 8, + }, + + PeerMemory: rcmgr.MemoryLimit{ + MemoryFraction: 0.125 / 16, + MinMemory: 64 << 20, + MaxMemory: 128 << 20, + }, + + ConnBaseLimit: rcmgr.BaseLimit{ + ConnsInbound: 1, + ConnsOutbound: 1, + Conns: 1, + FD: 1, + }, + + ConnMemory: 1 << 20, + + StreamBaseLimit: rcmgr.BaseLimit{ + StreamsInbound: 1, + StreamsOutbound: 1, + Streams: 1, + }, + + StreamMemory: 16 << 20, +} + +// newDefaultLimiter creates a static limiter with the default limits. +// This is a vendored copy of +// https://github.com/libp2p/go-libp2p-resource-manager/blob/v0.1.5/limit_static.go#L78 +func newDefaultLimiter() *rcmgr.BasicLimiter { + return rcmgr.NewStaticLimiter(defaultLimits) +} + +// setDefaultServiceLimits sets the default limits for bundled libp2p services. +// This is a vendored copy of +// https://github.com/libp2p/go-libp2p/blob/v0.18.0/limits.go +func setDefaultServiceLimits(limiter *rcmgr.BasicLimiter) { + if limiter.ServiceLimits == nil { + limiter.ServiceLimits = make(map[string]rcmgr.Limit) + } + if limiter.ServicePeerLimits == nil { + limiter.ServicePeerLimits = make(map[string]rcmgr.Limit) + } + if limiter.ProtocolLimits == nil { + limiter.ProtocolLimits = make(map[protocol.ID]rcmgr.Limit) + } + if limiter.ProtocolPeerLimits == nil { + limiter.ProtocolPeerLimits = make(map[protocol.ID]rcmgr.Limit) + } + + // identify + setServiceLimits(limiter, identify.ServiceName, + limiter.DefaultServiceLimits. + WithMemoryLimit(1, 4<<20, 64<<20). // max 64MB service memory + WithStreamLimit(128, 128, 256), // max 256 streams -- symmetric + peerLimit(16, 16, 32)) + + setProtocolLimits(limiter, identify.ID, + limiter.DefaultProtocolLimits.WithMemoryLimit(1, 4<<20, 32<<20), + peerLimit(16, 16, 32)) + setProtocolLimits(limiter, identify.IDPush, + limiter.DefaultProtocolLimits.WithMemoryLimit(1, 4<<20, 32<<20), + peerLimit(16, 16, 32)) + setProtocolLimits(limiter, identify.IDDelta, + limiter.DefaultProtocolLimits.WithMemoryLimit(1, 4<<20, 32<<20), + peerLimit(16, 16, 32)) + + // ping + setServiceLimits(limiter, ping.ServiceName, + limiter.DefaultServiceLimits. + WithMemoryLimit(1, 4<<20, 64<<20). // max 64MB service memory + WithStreamLimit(128, 128, 128), // max 128 streams - asymmetric + peerLimit(2, 3, 4)) + setProtocolLimits(limiter, ping.ID, + limiter.DefaultProtocolLimits.WithMemoryLimit(1, 4<<20, 64<<20), + peerLimit(2, 3, 4)) + + // autonat + setServiceLimits(limiter, autonat.ServiceName, + limiter.DefaultServiceLimits. + WithMemoryLimit(1, 4<<20, 64<<20). // max 64MB service memory + WithStreamLimit(128, 128, 128), // max 128 streams - asymmetric + peerLimit(2, 2, 2)) + setProtocolLimits(limiter, autonat.AutoNATProto, + limiter.DefaultProtocolLimits.WithMemoryLimit(1, 4<<20, 64<<20), + peerLimit(2, 2, 2)) + + // holepunch + setServiceLimits(limiter, holepunch.ServiceName, + limiter.DefaultServiceLimits. + WithMemoryLimit(1, 4<<20, 64<<20). // max 64MB service memory + WithStreamLimit(128, 128, 256), // max 256 streams - symmetric + peerLimit(2, 2, 2)) + setProtocolLimits(limiter, holepunch.Protocol, + limiter.DefaultProtocolLimits.WithMemoryLimit(1, 4<<20, 64<<20), + peerLimit(2, 2, 2)) + + // relay/v1 + setServiceLimits(limiter, relayv1.ServiceName, + limiter.DefaultServiceLimits. + WithMemoryLimit(1, 4<<20, 64<<20). // max 64MB service memory + WithStreamLimit(1024, 1024, 1024), // max 1024 streams - asymmetric + peerLimit(64, 64, 64)) + + // relay/v2 + setServiceLimits(limiter, relayv2.ServiceName, + limiter.DefaultServiceLimits. + WithMemoryLimit(1, 4<<20, 64<<20). // max 64MB service memory + WithStreamLimit(1024, 1024, 1024), // max 1024 streams - asymmetric + peerLimit(64, 64, 64)) + + // circuit protocols, both client and service + setProtocolLimits(limiter, circuit.ProtoIDv1, + limiter.DefaultProtocolLimits. + WithMemoryLimit(1, 4<<20, 64<<20). + WithStreamLimit(1280, 1280, 1280), + peerLimit(128, 128, 128)) + setProtocolLimits(limiter, circuit.ProtoIDv2Hop, + limiter.DefaultProtocolLimits. + WithMemoryLimit(1, 4<<20, 64<<20). + WithStreamLimit(1280, 1280, 1280), + peerLimit(128, 128, 128)) + setProtocolLimits(limiter, circuit.ProtoIDv2Stop, + limiter.DefaultProtocolLimits. + WithMemoryLimit(1, 4<<20, 64<<20). + WithStreamLimit(1280, 1280, 1280), + peerLimit(128, 128, 128)) + +} + +func setServiceLimits(limiter *rcmgr.BasicLimiter, svc string, limit rcmgr.Limit, peerLimit rcmgr.Limit) { + if _, ok := limiter.ServiceLimits[svc]; !ok { + limiter.ServiceLimits[svc] = limit + } + if _, ok := limiter.ServicePeerLimits[svc]; !ok { + limiter.ServicePeerLimits[svc] = peerLimit + } +} + +func setProtocolLimits(limiter *rcmgr.BasicLimiter, proto protocol.ID, limit rcmgr.Limit, peerLimit rcmgr.Limit) { + if _, ok := limiter.ProtocolLimits[proto]; !ok { + limiter.ProtocolLimits[proto] = limit + } + if _, ok := limiter.ProtocolPeerLimits[proto]; !ok { + limiter.ProtocolPeerLimits[proto] = peerLimit + } +} + +func peerLimit(numStreamsIn, numStreamsOut, numStreamsTotal int) rcmgr.Limit { + return &rcmgr.StaticLimit{ + // memory: 256kb for window buffers plus some change for message buffers per stream + Memory: int64(numStreamsTotal * (256<<10 + 16384)), + BaseLimit: rcmgr.BaseLimit{ + StreamsInbound: numStreamsIn, + StreamsOutbound: numStreamsOut, + Streams: numStreamsTotal, + }, + } +} From bc365724bb841b835c81c11ca57e815993068cad Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 6 Apr 2022 23:59:54 +0200 Subject: [PATCH 19/22] refactor: adjustedDefaultLimits Cleans up the way we initialize defaults and adds a fix for case when connection manager runs with high limits. It also hides `Swarm.ResourceMgr.Limits` until we have a better understanding what syntax makes sense. --- config/swarm.go | 29 +++++++++++++-- core/node/groups.go | 2 +- core/node/libp2p/rcmgr.go | 44 +++++++++------------- core/node/libp2p/rcmgr_defaults.go | 60 ++++++++++++++++++++++++++---- docs/config.md | 25 ++++--------- 5 files changed, 103 insertions(+), 57 deletions(-) diff --git a/config/swarm.go b/config/swarm.go index a18a2fd5dae..be420298497 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -139,8 +139,8 @@ type ResourceMgr struct { // Enables the Network Resource Manager feature Enabled Flag `json:",omitempty"` - // Limits is a map of Resource Scope. - Limits map[string]ResourceMgrScopeConfig `json:",omitempty"` + /* TODO: decide if and how we want to expose limits in our config + Limits *ResourceMgrScopeConfig `json:",omitempty"` */ } const ( @@ -151,7 +151,30 @@ const ( ResourceMgrPeerScopePrefix = "peer:" ) -// libp2p Network Resource Manager config for a scope (ipfs swarm stats|limit) +/* TODO: decide if and how we want to expose limits in our config +type ResourceMgrLimitsConfig struct { + System *ResourceMgrScopeConfig `json:",omitempty"` + Transient *ResourceMgrScopeConfig `json:",omitempty"` + + ServiceDefault *ResourceMgrScopeConfig `json:",omitempty"` + ServicePeerDefault *ResourceMgrScopeConfig `json:",omitempty"` + Service map[string]ResourceMgrScopeConfig `json:",omitempty"` + ServicePeer map[string]ResourceMgrScopeConfig `json:",omitempty"` + + ProtocolDefault *ResourceMgrScopeConfig `json:",omitempty"` + ProtocolPeerDefault *ResourceMgrScopeConfig `json:",omitempty"` + Protocol map[string]ResourceMgrScopeConfig `json:",omitempty"` + ProtocolPeer map[string]ResourceMgrScopeConfig `json:",omitempty"` + + PeerDefault *ResourceMgrScopeConfig `json:",omitempty"` + Peer map[string]ResourceMgrScopeConfig `json:",omitempty"` + + Conn *ResourceMgrScopeConfig `json:",omitempty"` + Stream *ResourceMgrScopeConfig `json:",omitempty"` +} +*/ + +// libp2p Network Resource Manager config for a scope type ResourceMgrScopeConfig struct { Dynamic bool `json:",omitempty"` // set if Dynamic is false diff --git a/core/node/groups.go b/core/node/groups.go index a713f36ca37..7f4cd8b97a2 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -145,7 +145,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { BaseLibP2P, // Services (resource management) - fx.Provide(libp2p.ResourceManager(cfg.Swarm.ResourceMgr)), + fx.Provide(libp2p.ResourceManager(cfg.Swarm)), fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), fx.Provide(libp2p.SmuxTransport(cfg.Swarm.Transports)), diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 3b9d8b70dc2..54ff4c54e27 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -25,14 +25,14 @@ const NetLimitTraceFilename = "rcmgr.json.gz" var NoResourceMgrError = fmt.Errorf("missing ResourceMgr: make sure the daemon is running with Swarm.ResourceMgr.Enabled") -func ResourceManager(cfg config.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network.ResourceManager, Libp2pOpts, error) { +func ResourceManager(cfg config.SwarmConfig) func(fx.Lifecycle, repo.Repo) (network.ResourceManager, Libp2pOpts, error) { return func(lc fx.Lifecycle, repo repo.Repo) (network.ResourceManager, Libp2pOpts, error) { var limiter *rcmgr.BasicLimiter var manager network.ResourceManager var opts Libp2pOpts // Config Swarm.ResourceMgr.Enabled decides if we run a real manager - enabled := cfg.Enabled.WithDefault(false) + enabled := cfg.ResourceMgr.Enabled.WithDefault(false) /// ENV overrides Config (if present) switch os.Getenv("LIBP2P_RCMGR") { @@ -50,25 +50,23 @@ func ResourceManager(cfg config.ResourceMgr) func(fx.Lifecycle, repo.Repo) (netw return nil, opts, fmt.Errorf("error opening IPFS_PATH: %w", err) } - // Try defaults from limit.json if provided - // (a convention to make libp2p team life easier) + // Create limiter: + // - parse $IPFS_PATH/limits.json if exists + // - use defaultLimits from rcmgr_defaults.go + defaultLimits := adjustedDefaultLimits(cfg) limitFilePath := filepath.Join(repoPath, NetLimitDefaultFilename) - _, err = os.Stat(limitFilePath) - if !errors.Is(err, os.ErrNotExist) { - limitFile, err := os.Open(limitFilePath) + limitFile, err := os.Open(limitFilePath) + switch { + case err == nil: + defer limitFile.Close() + limiter, err = rcmgr.NewLimiterFromJSON(limitFile, defaultLimits) if err != nil { - return nil, opts, fmt.Errorf("error opening limit JSON file %q: %w", limitFilePath, err) + return nil, opts, fmt.Errorf("error parsing libp2p limit file: %w", err) } - defer limitFile.Close() //nolint:errcheck - limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitFile) - if err != nil { - return nil, opts, fmt.Errorf("error parsing limit file: %w", err) - } - - } else { - // Use defaults from rcmgr_defaults.go - log.Debug("limit file %s not found, creating a default resource manager", NetLimitDefaultFilename) - limiter = newDefaultLimiter() // see rcmgr_defaults.go + case errors.Is(err, os.ErrNotExist): + limiter = rcmgr.NewStaticLimiter(defaultLimits) + default: + return nil, opts, err } setDefaultServiceLimits(limiter) // see rcmgr_defaults.go @@ -82,15 +80,7 @@ func ResourceManager(cfg config.ResourceMgr) func(fx.Lifecycle, repo.Repo) (netw manager, err = rcmgr.NewResourceManager(limiter, ropts...) if err != nil { - return nil, opts, fmt.Errorf("error creating resource manager: %w", err) - } - - // Apply user-defined Swarm.ResourceMgr.Limits - for scope, userLimit := range cfg.Limits { - err := NetSetLimit(manager, scope, userLimit) - if err != nil { - return nil, opts, fmt.Errorf("error while applying Swarm.ResourceMgr.Limits for scope %q: %w", scope, err) - } + return nil, opts, fmt.Errorf("error creating libp2p resource manager: %w", err) } } else { diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go index b1942ffa662..dddc2b32411 100644 --- a/core/node/libp2p/rcmgr_defaults.go +++ b/core/node/libp2p/rcmgr_defaults.go @@ -1,6 +1,9 @@ package libp2p import ( + "math/bits" + + config "github.com/ipfs/go-ipfs/config" "github.com/libp2p/go-libp2p-core/protocol" rcmgr "github.com/libp2p/go-libp2p-resource-manager" "github.com/libp2p/go-libp2p/p2p/host/autonat" @@ -16,10 +19,58 @@ import ( // We keep vendored copy to ensure go-ipfs is not impacted when go-libp2p decides // to change defaults in any of the future releases. +// adjustedDefaultLimits allows for tweaking defaults based on external factors, +// such as values in Swarm.ConnMgr.HiWater config. +func adjustedDefaultLimits(cfg config.SwarmConfig) rcmgr.DefaultLimitConfig { + + // Return to use unmodified static limits based on values from go-libp2p 0.18 + // return defaultLimits + + // Adjust limits + // (based on https://github.com/filecoin-project/lotus/pull/8318/files) + // - give it more memory, up to 4G, min of 1G + // - if Swarm.ConnMgr.HighWater is too high, adjust Conn/FD/Stream limits + defaultLimits := staticDefaultLimits.WithSystemMemory(.125, 1<<30, 4<<30) + + // Do we need to adjust due to Swarm.ConnMgr.HighWater? + if cfg.ConnMgr.Type == "basic" { + maxconns := cfg.ConnMgr.HighWater + if 2*maxconns > defaultLimits.SystemBaseLimit.ConnsInbound { + // adjust conns to 2x to allow for two conns per peer (TCP+QUIC) + defaultLimits.SystemBaseLimit.ConnsInbound = logScale(2 * maxconns) + defaultLimits.SystemBaseLimit.ConnsOutbound = logScale(2 * maxconns) + defaultLimits.SystemBaseLimit.Conns = logScale(4 * maxconns) + + defaultLimits.SystemBaseLimit.StreamsInbound = logScale(16 * maxconns) + defaultLimits.SystemBaseLimit.StreamsOutbound = logScale(64 * maxconns) + defaultLimits.SystemBaseLimit.Streams = logScale(64 * maxconns) + + if 2*maxconns > defaultLimits.SystemBaseLimit.FD { + defaultLimits.SystemBaseLimit.FD = logScale(2 * maxconns) + } + + defaultLimits.ServiceBaseLimit.StreamsInbound = logScale(8 * maxconns) + defaultLimits.ServiceBaseLimit.StreamsOutbound = logScale(32 * maxconns) + defaultLimits.ServiceBaseLimit.Streams = logScale(32 * maxconns) + + defaultLimits.ProtocolBaseLimit.StreamsInbound = logScale(8 * maxconns) + defaultLimits.ProtocolBaseLimit.StreamsOutbound = logScale(32 * maxconns) + defaultLimits.ProtocolBaseLimit.Streams = logScale(32 * maxconns) + } + } + + return defaultLimits +} + +func logScale(val int) int { + bitlen := bits.Len(uint(val)) + return 1 << bitlen +} + // defaultLimits are the limits used by the default rcmgr limiter constructors. // This is a vendored copy of // https://github.com/libp2p/go-libp2p-resource-manager/blob/v0.1.5/limit_defaults.go#L49 -var defaultLimits = rcmgr.DefaultLimitConfig{ +var staticDefaultLimits = rcmgr.DefaultLimitConfig{ SystemBaseLimit: rcmgr.BaseLimit{ StreamsInbound: 4096, StreamsOutbound: 16384, @@ -134,13 +185,6 @@ var defaultLimits = rcmgr.DefaultLimitConfig{ StreamMemory: 16 << 20, } -// newDefaultLimiter creates a static limiter with the default limits. -// This is a vendored copy of -// https://github.com/libp2p/go-libp2p-resource-manager/blob/v0.1.5/limit_static.go#L78 -func newDefaultLimiter() *rcmgr.BasicLimiter { - return rcmgr.NewStaticLimiter(defaultLimits) -} - // setDefaultServiceLimits sets the default limits for bundled libp2p services. // This is a vendored copy of // https://github.com/libp2p/go-libp2p/blob/v0.18.0/limits.go diff --git a/docs/config.md b/docs/config.md index 8b6d3aabe46..82eb8af243e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -132,7 +132,6 @@ config file at runtime. - [`Swarm.ConnMgr.GracePeriod`](#swarmconnmgrgraceperiod) - [`Swarm.ResourceMgr`](#swarmresourcemgr) - [`Swarm.ResourceMgr.Enabled`](#swarmresourcemgrenabled) - - [`Swarm.ResourceMgr.Limits`](#swarmresourcemgrlimits) - [`Swarm.Transports`](#swarmtransports) - [`Swarm.Transports.Network`](#swarmtransportsnetwork) - [`Swarm.Transports.Network.TCP`](#swarmtransportsnetworktcp) @@ -1647,16 +1646,14 @@ Default: `false` Type: `flag` + + ### `Swarm.Transports` Configuration section for libp2p transports. An empty configuration will apply From a43a71de507d0478c4b27f83a5c5bb63905cafc0 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 8 Apr 2022 00:39:15 +0200 Subject: [PATCH 20/22] chore: cleanup after a review --- core/commands/config.go | 4 ++-- core/commands/swarm.go | 4 ++-- core/node/libp2p/rcmgr.go | 12 ++++++------ docs/config.md | 10 +++++----- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/core/commands/config.go b/core/commands/config.go index 7c4ae78f12a..3f009de9a0d 100644 --- a/core/commands/config.go +++ b/core/commands/config.go @@ -215,11 +215,11 @@ NOTE: For security reasons, this command will omit your private key and remote s return cmds.EmitOnce(res, &cfg) }, Encoders: cmds.EncoderMap{ - cmds.Text: HumanJsonEncoder, + cmds.Text: HumanJSONEncoder, }, } -var HumanJsonEncoder = cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *map[string]interface{}) error { +var HumanJSONEncoder = cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *map[string]interface{}) error { buf, err := config.HumanOutput(out) if err != nil { return err diff --git a/core/commands/swarm.go b/core/commands/swarm.go index fdd61308fa9..61f40e456aa 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -356,7 +356,7 @@ The output of this command is JSON. return cmds.EmitOnce(res, b) }, Encoders: cmds.EncoderMap{ - cmds.Text: HumanJsonEncoder, + cmds.Text: HumanJSONEncoder, }, } @@ -433,7 +433,7 @@ For permanent limits set Swarm.ResourceMgr.Limits in the $IPFS_PATH/config file. return cmds.EmitOnce(res, b) }, Encoders: cmds.EncoderMap{ - cmds.Text: HumanJsonEncoder, + cmds.Text: HumanJSONEncoder, }, } diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index 54ff4c54e27..d0bccd277fe 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -155,7 +155,7 @@ func NetStat(mgr network.ResourceManager, scope string) (NetStatOut, error) { return result, err case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): - svc := scope[4:] + svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) err = mgr.ViewService(svc, func(s network.ServiceScope) error { stat := s.Stat() result.Services = map[string]network.ScopeStat{ @@ -166,7 +166,7 @@ func NetStat(mgr network.ResourceManager, scope string) (NetStatOut, error) { return result, err case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): - proto := scope[6:] + proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { stat := s.Stat() result.Protocols = map[string]network.ScopeStat{ @@ -177,7 +177,7 @@ func NetStat(mgr network.ResourceManager, scope string) (NetStatOut, error) { return result, err case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): - p := scope[5:] + p := strings.TrimPrefix(scope, config.ResourceMgrPeerScopePrefix) pid, err := peer.Decode(p) if err != nil { return result, fmt.Errorf("invalid peer ID: %q: %w", p, err) @@ -251,21 +251,21 @@ func NetLimit(mgr network.ResourceManager, scope string) (config.ResourceMgrScop return result, err case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): - svc := scope[4:] + svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) err := mgr.ViewService(svc, func(s network.ServiceScope) error { return getLimit(s) }) return result, err case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): - proto := scope[6:] + proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) err := mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { return getLimit(s) }) return result, err case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): - p := scope[5:] + p := strings.TrimPrefix(scope, config.ResourceMgrPeerScopePrefix) pid, err := peer.Decode(p) if err != nil { return result, fmt.Errorf("invalid peer ID: %q: %w", p, err) diff --git a/docs/config.md b/docs/config.md index 82eb8af243e..519a7c10546 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1633,7 +1633,7 @@ Type: `duration` ### `Swarm.ResourceMgr` The [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) allows setting limits per a scope, -and track recource usage over time. +and tracking recource usage over time. #### `Swarm.ResourceMgr.Enabled` @@ -1646,7 +1646,7 @@ Default: `false` Type: `flag` -